简体   繁体   English

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

[英]How to specialize template type of a generic class in typescript?

Is it possible to specialize the template type of a generic class in a generic function in typescript ? 是否可以在typescript中的泛型函数中专门化泛型类的模板类型?

Suppose I have a generic interface and a function which takes the interface constructor as argument: 假设我有一个通用接口和一个将接口构造函数作为参数的函数:

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;
    }
}

then I provide the class implements IA<T> , which is 然后我提供了类实现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

How can I write the function g or the class A so that function g can specialize the correct template type due to the argument pass in? 如何编写函数g或类A以使函数g由于传递了参数而可以专用于正确的模板类型? I want to the final t has the type (arg: {key: string}) => A 我想最后的t具有类型(arg: {key: string}) => A

This type for constructor parameter for g 此类型为g constructor参数

 constructor: { new(): IAType }

does not really impose a constraint that func() in IAType must have T as its argument type. 并没有真正施加约束, IAType中的func()必须以T作为其参数类型。 The only constraint is IAType extends IA<T> , which means that func in IAType is allowed to have any type as long as it's compatible with func(arg: T) . 唯一的约束是IAType extends IA<T> ,这意味着IAType中的func可以具有任何类型,只要它与func(arg: T)兼容即可。 The inference algorithm probably starts with minimal type which is {} , verifies that func(arg: {}) is compatible with func(arg: T) and just stops there. 推论算法可能以最小类型{}开头,验证func(arg: {})func(arg: T)兼容并止于此。

Being more strict about constructor type helps: 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

Both IA<T> & IAType are necessary. IA<T> & IAType都是必需的。 If you have only IA<T> , arg type will be inferred as desired, but the return type would be only IA<T> , not A . 如果只有IA<T> ,则将根据需要推断arg类型,但是返回类型将仅为IA<T> ,而不是A

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM