Typescript泛型和功能作为类属性类型

时间:2018-10-26 12:08:26

标签: typescript generics typescript3.0

我有以下代码:

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.

我不知道这里到底有什么问题。如何确定valueT类型还是函数返回的值是T类型。

目前我有一种解决方法,(我认为)这不是很好:

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

有人可以帮助我吗?谢谢! :-)

1 个答案:

答案 0 :(得分:0)

如果调用方将T设置为函数类型(例如T = (x: number) => number)并传递类型为T的值(即要求一个论点。您的代码将尝试不带任何参数地调用此函数。

通过将T约束为具有相同属性但没有调用签名的映射类型,可以向编译器提示您不希望T成为函数类型。也就是说,您可以将类Test的声明更改为:

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

然后错误应该消失。但是,编译器不会阻止您实际使用函数类型实例化T,因为函数类型确实扩展了相同的类型,并且删除了调用签名,因此请小心。 (因此,令我惊讶的是,上述技术可以消除错误。可以说缺少错误可能是一个错误。如果该错误得到修复,我想您只是回到了当前的解决方法。)