In TypeScript I can define the type of a variable as the type of a class. For example:
class MyClass { ... }
let myVar: typeof MyClass = MyClass;
Now I want to use this with a generic class, something like this:
class MyManager<T> {
constructor(cls: typeof T) { ... }
/* some other methods, which uses instances of T */
}
let test = new MyManager(MyClass); /* <MyClass> should be implied by the parameter */
So, I want to give my manager class another class (its constructor), because the manager needs to retreive static information associated with the class.
When compiling my code, it says that it cannot find name 'T', where my constructor is.
Any idea how to solve it?
You can use this type of constructors: { new (): ClassType }
.
class MyManager<T> {
private cls: { new(): T };
constructor(cls: { new(): T }) {
this.cls = cls;
}
createInstance(): T {
return new this.cls();
}
}
class MyClass {}
let test = new MyManager(MyClass);
let a = test.createInstance();
console.log(a instanceof MyClass); // true
The proper way to describe a class type in typescript is using the following:
{ new(): Class }
For example in the typescript lib.d.ts ArrayConstructor
:
interface ArrayConstructor {
new (arrayLength?: number): any[];
new <T>(arrayLength: number): T[];
new <T>(...items: T[]): T[];
(arrayLength?: number): any[];
<T>(arrayLength: number): T[];
<T>(...items: T[]): T[];
isArray(arg: any): arg is Array<any>;
readonly prototype: Array<any>;
}
Here you have 3 different ctor signatures plus a bunch of static functions.
In your case you can also define it like:
interface ClassConstructor<T> {
new(): T;
}
class MyManager<T> {
private cls: ClassConstructor<T>;
constructor(cls: ClassConstructor<T>) {
this.cls = cls;
}
createInstance(): T {
return new this.cls();
}
}