Eric Dobbs Eric Dobbs - 11 months ago 31
TypeScript Question

In TypeScript, can I instantiate from a property defined as a class (not instance) derived from an abstract class?

In a nutshell, I want to create a class that stores the type that it will create (sort of a factory object). Below is an example of my problem fitted to a set of sample classes:

abstract class Shape {
size: number;
abstract getArea(): number;

class Square extends Shape {
getArea(): number { return this.size * this.size; }

class ShapeGenerator {
shapeType: typeof Shape;
createShape(): Shape { return new this.shapeType() } // Here's the problem!

var squareGenerator = new ShapeGenerator();
squareGenerator.shapeType = Square;

var mySquare = squareGenerator.createShape();
mySquare.size = 5;

I want shapeType to represent the class that I'll be instantiating, but I want to restrict that to be something derived from Shape. Of course I can't new up a Shape, but I can't figure out how to write out that shapeType will be derived from Shape, but won't actually be the abstract Shape class.

I'm not sure if it's possible to use a type guard to explain that this will be a concrete class. Perhaps there's another way around this I haven't considered at all. My current possible solutions are to just change createShape's return type to any, or to require a function as a constructor parameter that would take the place of createShape.

Answer Source


shapeType: { new(): Shape; };