TypeScript中的通用构造函数参考和静态方法

时间:2019-04-15 13:29:48

标签: typescript generics

请考虑以下代码:

class Wrapper<T> {

    public static forConstructor<S extends Object>(construc: { new (...args: any[]): S }): Wrapper<S> {
        return new Wrapper<S>();
    }
}

class A {
    private aaa: string = null;
}

class B {
    private bbb: string = null;
}

const wrapper: Wrapper<A> = Wrapper.forConstructor(B);// LINE X

在第X行Wrapper<A> = Wrapper<B>上,这是错误的,但是TypeScript在此行不显示错误。我怎么了?

2 个答案:

答案 0 :(得分:1)

当前Wrapper<A>Wrapper<B>在结构上兼容。如果将传递的构造函数存储为字段(例如),则会出现错误:

type Constructor<T> = new (...args: any[]) => T;

class Wrapper<T> {
    constructor(private c: Constructor<T>){}

    public static forConstructor<T>(construc: Constructor<T>): Wrapper<T> {
        return new Wrapper<T>(construc);
    }
}

class A {
    private aaa: string = null;
}

class B {
    private bbb: string = null;
}

const wrapper: Wrapper<A> = Wrapper.forConstructor(B); // error

Playground

答案 1 :(得分:0)

静态方法不能使用实例类型参数Wrapper<T>,因为静态方法不受实例限制。您的方法签名<S extends Object本质上是any对象。因此根本没有类型安全性。这就是为什么tscompiler不会抱怨

const wrapper: Wrapper<A> = Wrapper.forConstructor(B);// LINE X

但是,如果您实际使用实例类型参数并将其设置为非静态,则它将发出例如

class Wrapper<S> {

    public forConstructor(construc: { new (...args: any[]): S }): Wrapper<S> {
        return new Wrapper<S>();
    }
}

const wrapper: Wrapper<A> = new Wrapper();
wrapper.forConstructor(B); // will not work