通用静态类方法

时间:2019-02-23 16:13:15

标签: typescript

如何键入在扩展类上使用静态属性的方法?

给出javascript:

class Animal {}
Animal.makeNoise = (language) => this.sounds[language];

class Dog extends Animal {}
Dog.sounds = {
  english: 'woof-woof',
  portuguese: 'au-au'
}

我认为这可能有效

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"

但是我找不到一种方法来引用每个扩展类的this.sounds。有什么正确的方法吗?

1 个答案:

答案 0 :(得分:2)

由于您希望静态方法可用于任何派生类,因此可以使用this参数捕获派生类中sound的实际类型。然后,您可以使用此类型信息提取实际的声音类型:

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"