Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating child class from a static method in base class, using TypeScript

Tags:

typescript

Being new to TypeScript, what is the best method to implement a static factory in a base class that instantiates the child class type. For instance, consider a findAll method in a base model class:

class BaseModel {
  static data: {}[];
  static findAll() {
    return this.data.map((x) => new this(x));
  }
  constructor(readonly attributes) {
  }
}

class Model extends BaseModel {
  static data = [{id: 1}, {id: 2}];
  constructor(attributes) {
    super(attributes);
  }
}

const a = Model.findAll();  // This is BaseModel[] not Model[]

This returns BaseModel[] rather than Model[].

like image 333
Tristan Avatar asked Dec 03 '25 20:12

Tristan


1 Answers

To answer my own question, this turns out to be a well known issue in TypeScript. The Github issue Polymorphic this for static methods has a long discussion. The solution is as follows:

export type StaticThis<T> = { new (): T };

export class Base {
    static create<T extends Base>(this: StaticThis<T>) {
        const that = new this();
        return that;
    }
    baseMethod() { }
}

export class Derived extends Base {
    derivedMethod() { }
}

// works
Base.create().baseMethod();
Derived.create().baseMethod();
// works too
Derived.create().derivedMethod();
// does not work (normal)
Base.create().derivedMethod();
like image 66
Tristan Avatar answered Dec 05 '25 10:12

Tristan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!