Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create an abstract factory pattern in Typescript?

I am trying to implement a standard abstract factory pattern in Typescript, but the compiler is not being cooperative. Here is a simplified version of my code:

abstract class Model { }
class User extends Model { }

abstract class ModelFactory<T extends typeof Model> {
   constructor(private modelConstructor: T) {}

   public create(): T {
     return new (this.modelConstructor)();  // ERROR HERE
   }
}
class UserFactory extends ModelFactory<typeof User> {
  constructor() {
    super(User);
  }
}

let user: User;
user  = new UserFactory().create();

However, when I compile using tsc 2.1, I get the following error at the line indicated above:

model.ts(8,13): error TS2511: Cannot create an instance of the abstract class 'Model'.

If I remove type safety and convert the line to this:

return new (this.modelConstructor as any)();

The code is compiled without errors. However, this is unfortunate. Is there any way to make this code compilable without using a cast? And if not, why not?

like image 331
Andrew Eisenberg Avatar asked Dec 23 '22 21:12

Andrew Eisenberg


1 Answers

You should use this pattern instead:

abstract class ModelFactory<T extends Model> {
    constructor(private modelConstructor: new () => T) { }

    public create(): T {
        return new (this.modelConstructor)();  // OK!
    }
}

class UserFactory extends ModelFactory<User> {
    constructor() {
        super(User);
    }
}
like image 115
Ryan Cavanaugh Avatar answered Mar 23 '23 19:03

Ryan Cavanaugh