Следующий код пытается определить тип функции, которая вызывается без аргументов, если ее общий аргумент равен undefined
, но с 1 аргументом для любого другого типа аргумента. (Возможно, есть более эффективные способы сделать это, ссылки на которые я бы хотел видеть в комментариях, но вопрос в том, почему Typescript работает не так, как я ожидал.)
Когда T extends undefined
ложно, T
превращается в never
в ветке else, но только внутри списка параметров функции ...
type OptionalArgBroken<Arg> = Arg extends undefined ?
() => void :
(arg: Arg) => void;
const suppressArgBroken:OptionalArgBroken<undefined> = function() { };
suppressArgBroken(); // Fine
const haveArgBroken:OptionalArgBroken<boolean> = function(b:boolean) { };
haveArgBroken(true); // Type error
Как вы можете видеть на Playground, последняя строка выше дает ошибку типа
Аргумент типа "истина" не может быть назначен параметру типа "никогда". (2345)
Прочитав https://github.com/microsoft/TypeScript/issues/31751, Я попытался обернуть Arg
и undefined
в []
s, и это, похоже, устранило проблему:
type OptionalArgWorks<Arg> = [Arg] extends [undefined] ?
() => void :
(arg: Arg) => void;
const suppressArgWorks:OptionalArgWorks<undefined> = function() { };
suppressArgWorks(); // Fine
const haveArgWorks:OptionalArgWorks<boolean> = function(b:boolean) { };
haveArgWorks(true); // Fine
Несмотря на то, что это исправление сработало, это не та проблема:
type MakesSenseT = undefined extends undefined ? 'yes' : 'no'
const MakesSense:MakesSenseT = 'yes';
type ExtendsUndefined<T> = T extends undefined ? 'yes' : 'no'
const MakesSenseToo : ExtendsUndefined<undefined> = 'yes';
const MakesSenseThree : ExtendsUndefined<boolean> = 'no';
Почему мой исходный код не работал?
Ссылка на игровую площадку Typescript для приведенного выше кода