Проблема заключается в том, что машинопись не может много рассуждать об условных типах, пока в них все еще есть неразрешенные параметры (например, T
в функции).Таким образом, при обнаружении защиты типов typecript просто пересекает тип параметра с Function
, в результате чего (() => string) | (Exclude<T, Function> & Function)
все еще не вызывается.
Безусловно, самый простой способ обойти это - использовать типутверждение.
Вы также можете выразить условие по-другому.Функция должна иметь метод call
.Если мы ограничим T
, если у него есть член call
, он будет иметь тип, несовместимый с функцией call
, мы фактически исключим из функции T
:
function foo<T extends number | string | boolean | null | undefined | ({ call?: undefined; [k: string]: any }) = never>(value: T | (() => string)) {
let result: string;
if (typeof value === 'function') {
result = value(); // ok
} else {
result = value.toString();
}
console.log(result);
}
foo(1)
foo({
o: ""
})
foo(() => "");
foo(() => 1); // error
Возможно, новые функции с отрицательными типами улучшат возможности машинописи к рассуждению, когда задействованы параметры типа.Хотя Exclude
хорошо фильтрует тип, он не является 100% заменой отрицательного типа.