user5182503
user5182503

Reputation:

Generic constructor reference and static method in TypeScript

Please, consider the following code:

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

At LINE X Wrapper<A> = Wrapper<B> that is an wrong, however, TypeScript doesn't show error at this line. What is my mistake?

Upvotes: 1

Views: 208

Answers (2)

Aleksey L.
Aleksey L.

Reputation: 37938

Currently Wrapper<A> and Wrapper<B> are structurally compatible. If you'll store the passed constructor as a field (for example) you'll get an error:

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

Upvotes: 0

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37594

A static method can not use the instance type argument Wrapper<T> since static is not instance bounded. Your method signature <S extends Object essentially means any Object. So there is no type safety at all. That's why the tscompiler does not complain at

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

However if you actually use the instance type argument and make it non-static then it will complain e.g.

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

Upvotes: 0

Related Questions