how can I infer the return type of an instance method of an extending class? see psuedo code below
Note, this might not be possible, after looking into:
// Factory.ts
export default class Factory {
static make(...params: any[]): FactorySubclass["make"] {
// @ts-ignore
return new this(...params).make();
}
make() {
throw new Error("Not implemented");
}
}
// CarFactory.ts
class CarFactory extends Factory {
make() {
return "hello";
}
}
const instance = CarFactory.make(); // should infer "hello"
No need for the instanceof.
In an execution context, Factory['make'] refers to the make property of the Factory class, which in this case is the make() static method. In a type context, however, Factory['make'] refers to the make property of the Factory type, which in this case is the make() instance method.
So, this will work as per your requirements:
class Factory {
static make(...params: any[]): ReturnType<Factory['make']> {
return new this(...params).make();
}
make() {
throw new Error("Not implemented");
}
}
const x = Factory.make(); // correctly infers the type of x as "void"
The TypeScript 2.1 release notes refer to this notation as indexed access types or lookup types.
type m = Factory['make']; // defines the type m as "() => void"
For the updated question, to get the return type of the make() method of an extending class to be inferred correctly, you can do so by using a generic parameter to refer to the class type's constructor (see here), and making sure that the base class' make() instance method's return type is compatible with that of the implementing class, e.g. by making it return any:
class Factory {
static make<T extends Factory>(
this: { new (...params: any[]): T },
...params: any[]
): ReturnType<T['make']> {
return new this(...params).make();
}
make(): any {
throw new Error('Not implemented');
}
}
class CarFactory extends Factory {
make() {
return 'hello';
}
}
const x = Factory.make(); // infers the type of x as "any"
const y = CarFactory.make(); // infers the type of y as "string"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With