I have a scenario where I need a base class with a static method to instantiate the class. This base class is expected to be inherited by some children to have their own set of extra members.
Below is a minimal working example in JavaScript:
class A {
static create(value) {
return new this(value);
}
constructor(value) {
this.value = value;
}
}
class B extends A {
log() {
console.log(this.value);
}
}
const test1 = B.create('test1');
const test2 = B.create.call(B, 'test2');
const test3 = A.create.call(B, 'test3');
test1.log();
test2.log();
test3.log();
In the static create method, it instantiates the class using new this so that it will automatically references the immediate parent class.
If it were to be written without using this, then all child classes will not be able to instantiate with the static create method because now the logic is locked to A only:
class A {
static create(value){
return new A(value);
}
...
}
So far, so good.
Now, if I were to do this in TypeScript, it failed:
class A {
value: string;
static create(value: string) {
return new this(value);
}
constructor(value: string){
this.value = value;
}
}
class B extends A {
log(){
console.log(this.value);
}
}
const test1 = B.create('test1');
const test2 = B.create.call(B, 'test2');
const test3 = A.create.call(B, 'test3');
test1.log(); // Error: Property 'log' does not exist on type 'A'.
test2.log(); // Error: Property 'log' does not exist on type 'A'.
test3.log(); // Error: Property 'log' does not exist on type 'A'.
It appears that the type of this value is always locked to the root class.
Is there a way I can make the child classes infer this correctly?