Учитывая тип «что-нибудь, кроме функции ИЛИ функции», как я могу проверить, является ли это функцией в TypeScript? - PullRequest
0 голосов
/ 29 января 2019

Почему value не относится к типу () => string после проверки if (typeof value === 'function')?

Какую проверку необходимо выполнить, чтобы тип был выведен правильно (что делает приведение к нулю ненужным)?

function foo<T extends {}>(value: Exclude<T, Function> | (() => string)) {
    let result: string;

    if (typeof value === 'function') {
        result = value(); // Error: Type '(() => string) | (Exclude<T, Function> & Function)' has no compatible call signatures.
        result = (value as () => string)(); // works, but I don't like it
    } else {
        result = value.toString();
    }

    console.log(result);
}

1 Ответ

0 голосов
/ 30 января 2019

Проблема заключается в том, что машинопись не может много рассуждать об условных типах, пока в них все еще есть неразрешенные параметры (например, 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% заменой отрицательного типа.

...