Creating an instance of a child class from a static method in a base class using TypeScript

Being new to TypeScript, what's the best way to implement a static factory in a base class that instantiates a type of a child class. For example, consider a method findAllin the base class of a model:

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[], not Model[].

+3
source share
2 answers

To answer my question, this turns out to be a well known issue in TypeScript. The Github Problem Polymorphic for static methods has a lengthy 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();
+1
source

.

, ( ) - , , .

, : findAll(), , :

class BaseModel {
    static data: {}[];

    static _findAll<T extends BaseModel>(data: any[], Type): T[] {
        return data.map((x) => new Type(x));
    }

    constructor(readonly attributes) {
    }
}

class Model extends BaseModel {
    static data = [{ id: 1 }, { id: 2 }];

    constructor(attributes) {
        super(attributes);
    }

    static findAll() {
        return BaseModel._findAll(this.data, this);
    }
}

const a = Model.findAll();
0

Source: https://habr.com/ru/post/1618652/


All Articles