Jake H
Jake H

Reputation: 1740

Referencing the constructor function

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

Answers (2)

Brian Terlson
Brian Terlson

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

gaperton
gaperton

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

Related Questions