Тип шрифта T или функция () => использование T - PullRequest
1 голос
/ 28 марта 2020

Вы можете увидеть демонстрацию на этой игровой площадке .

Я сделал простой обобщенный тип c, который может представлять либо переменную, либо функцию, которая возвращает переменную. Но, к сожалению, он не работает с типичной проверкой typeof arg === 'function'. Выдает следующую ошибку:

This expression is not callable. Not all constituents of type '(() => T) | (T & Function)' are callable. Type 'T & Function' has no call signatures.

Есть ли способ заставить его работать без использования функции защиты типа?

type Initializer<T> = T | (() => T)

function correct(arg: Initializer<string>) {
    return typeof arg === 'function' ? arg() : arg
}

function wrong<T>(arg: Initializer<T>) {
    return typeof arg === 'function' ? arg() : arg // error here
}

const isFunction = (arg: any): arg is Function => typeof arg === 'function'

function correct_2<T>(arg: Initializer<T>) {
    return isFunction(arg) ? arg() : arg
}

1 Ответ

1 голос
/ 28 марта 2020

Вы можете написать:

type Initializer<T> = T extends any ? (T | (() => T)) : never

function correct<T>(arg: Initializer<T>): T {
    return typeof arg === 'function' ? arg() : arg // works
    // arg is Initializer<T> & Function in the true branch
}

const r1 = correct(2) // const r1: 2
const r2 = correct(() => 2) // const r2: number

В исходной версии arg разрешено до (() => T) | (T & Function) в истинной ветви. Очевидно, TS не может распознать для этого типа функции объединения, что обе составляющие могут вызываться . По крайней мере в вышеприведенной версии для компилятора очевидно, что вы можете вызывать arg после проверки функции.

Может также стоить создать проблему github для этого случая в Репозиторий TypeScript - по моему мнению T & Function должен представлять некоторый (широкий) тип функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...