Обобщения и функции Typescript как тип атрибута класса - PullRequest
0 голосов
/ 26 октября 2018

У меня есть следующий код:

class Test<T> {
    value: T | (() => T);

    determineValue(): T {
        if (typeof this.value === 'function') {
            return this.value();
        }
        return this.value;
    }
}

Компилятор выдает ошибку в строке с вызовом return this.value():

error TS2349: Cannot invoke an expression whose type lacks a call signature. Type '(() => T) | (T & Function)' has no compatible call signatures.

Не знаю, что именноздесь не так.Как я могу убедиться, что value имеет тип T или функция возвращает значение с типом T.

В данный момент у меня есть обходной путь, который (я думаю) недовольно мило:

return (<() => T>this.value)();

Может кто-нибудь мне помочь?Спасибо!: -)

1 Ответ

0 голосов
/ 26 октября 2018

Ваш код фактически не работает, если вызывающая сторона устанавливает T для типа функции, например, T = (x: number) => number, и передает значение типа T, то есть функцию, которая требует один аргумент.Ваш код попытается вызвать эту функцию без аргументов.

Вы можете дать компилятору подсказку, что вы не намерены T быть типом функции, ограничив T отображаемым типом, который имеетте же свойства, но без подписи вызовов.То есть вы бы изменили объявление класса Test на:

class Test<T extends { [P in keyof T]: T[P] }> { /* ... */ }

Тогда ошибка должна исчезнуть.Однако компилятор не остановит вас от фактического создания T с типом функции, потому что тип функции расширяет того же типа с удаленными сигнатурами вызовов, поэтому будьте осторожны.(Поэтому я удивлен, что приведенная выше методика работает для устранения ошибки. Возможно, отсутствие ошибки может быть ошибкой. Если ошибка исправлена, я думаю, вы просто вернетесь к своему текущему решению.)

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