typescript returtyp för instansmetod
hur kan jag härleda returtypen för en instansmetod i en utökande klass? se pseudokod nedan
Observera, detta kanske inte är möjligt efter att ha tittat på:
- https://github.com/microsoft/TypeScript/issues/5863
- https://github.com/Microsoft/TypeScript/issues/24364
- Mellankommande lösning för att komma åt klass typargument i statisk metod i Typescript
// 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"
Svar #1
Ingen anledning till instanceof.
I ett exekveringssammanhang avser Factory['make'] make-egenskapen hos Factory-klassen, vilket i det här fallet är den statiska metoden make(). I ett typ-sammanhang hänvisar dock Factory['make'] till make-egenskapen hos Factory typen, vilket i det här fallet är instansmetoden make().
Så, detta kommer att fungera enligt dina krav:
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"
TypeScript 2.1-utgivningsanteckningarna hänvisar till denna notation som indexed access types eller lookup types.
type m = Factory['make']; // defines the type m as "() => void"
Uppdatera
För den uppdaterade frågan, för att få returtypen av make()-metoden i en utökande klass att härledas korrekt, kan du göra det genom att använda en generisk parameter för att referera till klassens typkonstruktör (se här), och säkerställa att basklassens make()-instansmetods returtyp är kompatibel med den implementerande klassens, till exempel genom att låta den returnera 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"
