如何在打字稿中专门化泛型类的模板类型?

时间:2018-08-18 03:30:21

标签: typescript typescript-generics

是否可以在typescript的泛型函数中专门化泛型类的模板类型?

假设我有一个通用接口和一个以接口构造函数为参数的函数:

interface IA<T> {
    func(arg: T)
}

function g<T, IAType extends IA<T>>(
    constructor: { new(): IAType }
): (arg: T) => IAType {
    const ins = new constructor();
    return arg => {
        ins.func(arg);
        return ins;
    }
}

然后我提供类实现IA<T>

class A implements IA<{ key: string }> {
    func(arg: { key: string }) {
        console.log(arg.key);
    }
}

const t = g(A); // type of t is (arg: {}) => A

如何编写函数g或类A,以便函数g可以由于传递参数而专门化正确的模板类型?我想要最后的t类型为(arg: {key: string}) => A

1 个答案:

答案 0 :(得分:1)

constructor的{​​{1}}参数的这种类型

g

并没有真正施加约束, constructor: { new(): IAType } 中的func()必须具有IAType作为其参数类型。唯一的约束是T,这意味着IAType extends IA<T>中的func可以具有任何类型,只要它与IAType兼容即可。推理算法可能以最小类型func(arg: T)开始,验证{}func(arg: {})兼容并且就此停止。

更加严格的func(arg: T)类型有助于:

constructor

interface IA<T> { func(arg: T): void } function g<T, IAType extends IA<T>>( constructor: { new(): IA<T> & IAType } ): (arg: T) => IAType { const ins = new constructor(); return arg => { ins.func(arg); return ins; } } class A implements IA<{ key: string }> { func(arg: { key: string }) { console.log(arg.key); } } const t = g(A); // type of t is (arg: { key: string; }) => A 都是必需的。如果只有IA<T> & IAType,则会根据需要推断出IA<T>类型,但是返回类型将仅为arg,而不是IA<T>