Reputation:
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
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
Upvotes: 0
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