Reputation: 1740
Im wondering how I can get a reference to a types constructor to pass the function as a value. Basically, I would like to have a generic type registry that would allow instances to be created by calling a member function of a generic type registry instance.
For example:
class GeometryTypeInfo
{
constructor (public typeId: number, public typeName: string, public fnCtor: (...args: any[]) => IGeometry) {
}
createInstance(...args: any[]) : IGeometry { return this.fnCtor(args); }
}
}
Later:
class Point implements IGeometry {
constructor(public x: number, public y: number) { }
public static type_info = new GeometryTypeInfo(1, 'POINT', Point); // <- fails
// also fails:
// new GeometryTypeInfo(1, 'POINT', new Point);
// new GeometryTypeInfo(1, 'POINT', Point.prototype);
// new GeometryTypeInfo(1, 'POINT', Point.bind(this));
}
Anyone know if it is possible to reference a classes constructor function?
Upvotes: 19
Views: 21599
Reputation: 9650
You can use the constructor type literal or an object type literal with a construct signature to describe the type of a constructor (see, generally, section 3.5 of the language spec). To use your example, the following should work:
interface IGeometry {
x: number;
y: number;
}
class GeometryTypeInfo
{
constructor (public typeId: number, public typeName: string, public fnCtor: new (...args: any[]) => IGeometry) {
}
createInstance(...args: any[]) : IGeometry { return new this.fnCtor(args); }
}
class Point implements IGeometry {
constructor(public x: number, public y: number) { }
public static type_info = new GeometryTypeInfo(1, 'POINT', Point);
}
Notice the constructor type literal in GeometryTypeInfo
's constructor parameter list, and the new call in the implementation of createInstance
.
Upvotes: 22
Reputation: 3826
typeof YourClass
gives you constructor type which can be used in type annotations.
YourClass
and this.constructor
is constructor itself. So, this code compiles:
class A {}
const B : typeof A = A;
this.constructor
is not recognized as value of constructor type by TypeScript (which is funny), so in situations like that you need to use some cheating casting it no any
new (<any> this.constructor)()
That's it.
Upvotes: 10