Reputation: 526
How can you type a method which uses a static property on extended classes?
Given the javascript:
class Animal {}
Animal.makeNoise = (language) => this.sounds[language];
class Dog extends Animal {}
Dog.sounds = {
english: 'woof-woof',
portuguese: 'au-au'
}
I thought this might work
abstract class Animal {
static sounds: { [key in string]: false | string[] | string }
static makeNoise
= <S extends typeof Dog.sounds, L extends keyof S>(language: L): S[L]
=> this.sounds[language];
}
class Dog extends Animal {
static sounds: {
english: 'woof-woof',
portuguese: 'au-au'
}
}
Dog.makeNoise('english') // => "woof-woof"
But I cant find a way to reference the this.sounds
of every extended class. Is there any right way to do this yet?
Upvotes: 1
Views: 75
Reputation: 250406
Since you want the static method to work for any derived classes you can use the this
parameter to capture the actual type of sound
in the derived class. You can then use this type information to extract the actual sound type:
abstract class Animal {
static sounds: Record<string, false | string[] | string>
static makeNoise<TSounds extends typeof Animal['sounds'], L extends keyof TSounds>(this: { sounds: TSounds }, language: L): TSounds[L] {
return this.sounds[language];
}
}
class Dog extends Animal {
static sounds: {
english: 'woof-woof',
portuguese: 'au-au'
}
}
Dog.makeNoise('english') // => "woof-woof"
Upvotes: 2