Как предотвратить ненулевые типы в Typescript, включая дженерики? - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть ситуация, очень похожая на эту: https://github.com/microsoft/TypeScript/issues/22375.

Решение, данное там, в основном работает, за исключением случаев, когда я пишу простую оболочку, которая просто делегирует существующей реализации , Playground Link

Я не могу понять, как изменить данное решение для работы с общими c аргументами. Известно ли, что я не должен этого делать? Или я что-то упустил?

1 Ответ

0 голосов
/ 11 февраля 2020

Компилятор не может рассуждать о том, можно ли присвоить значение типу, который зависит от неуказанного параметра типа generi c, например T и D внутри реализации simpleWrapper(). Это особенно не может сделать это, когда тип является условным типом , как undefined extends T ? any : undefined. В основном он просто сдается и говорит, что любое написанное вами задание недействительно.

Существует несколько открытых проблем GitHub, связанных с этим ограничением, но я не знаю, решит ли кто-нибудь из них проблему данного кода, если они будут исправлены. Одним из них является microsoft / TypeScript # 13995 : компилятор не может сузить параметры типа generi c типа union, основанные на потоке управления. Другой вариант - microsoft / TypeScript # 33912 : компилятор не может определить, можно ли назначить что-либо условному типу generi c, особенно когда это возвращается из функции.

В большинстве ситуаций I Выяснилось, где эта проблема может быть решена путем разумного и разумного использования утверждения типа ; вы знаете, что-то безопасно, но компилятор - нет. Просто скажите это так:

function simpleWrapper<T, D>(t: T | undefined, d: D): T | D {
  return asDefinedOr(t as any, d);
}

Обратите внимание, что компилятор больше не пытается проверять безопасность типов для вас, поэтому вы должны быть осторожны.


В этом В конкретном случае кажется странным, что у вас go возникла проблема с функцией, которая пытается пожаловаться, если ее первый аргумент не может быть undefined, а затем обернуть его во что-то, что явно больше не заботится об этом, так как simpleWrapper(x, 0) не будет ошибкой. В этом случае вы можете просто использовать go для исходной реализации:

function simpleWrapper<T, D>(t: T | undefined, d: D): T | D {
  return t !== undefined ? t : d
}

Возможно, я не понимаю вариант использования, но я бы сказал, что вам следует избегать жонглирования вывода условных типов, если только вы это абсолютно необходимо.


Хорошо, надеюсь, это поможет; удачи!

Детская площадка ссылка на код

...