使用 TypeScript 接口中的字符串枚举值作为计算属性键

Fan*_*Lin 5 typescript typescript2.0

我想定义一个函数根据我给出的键返回不同类型的对象。createElement这基本上就像函数中使用的技巧一样

https://github.com/Microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L3117

但是,我想使用字符串枚举类型代替字符串文字。所以我写了这样的东西

class Dog {}
class Cat {}
class Bird {}

enum Kind {
  Dog = 'Dog',
  Cat = 'Cat',
  Bird = 'Bird'
}

interface KindMap {
  [Kind.Dog]: Dog
  [Kind.Cat]: Cat
  [Kind.Bird]: Bird
}

function getAnimal<K extends keyof KindMap> (key: K): KindMap[K] {
  switch (key) {
    case Kind.Dog:
      return new Dog()
    case Kind.Cat:
      return new Cat()
    case Kind.Bird:
      return new Bird()
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,TypeScript 似乎不喜欢我将enum Kind's 值放在接口内作为计算属性的方式,它抱怨

A computed property name in an interface must directly refer to a built-in symbol.
Run Code Online (Sandbox Code Playgroud)

问题来了,我已经在枚举中定义了常量,我不喜欢使用字符串文字,有什么方法可以使它起作用吗?这意味着使用 Kind 枚举的值作为KindMap.

Rob*_*ner 6

有时,一个简单的对象keyof比 TypeScript 中的枚举更简单:

class Dog { }
class Cat { }

const kindMap = {
    Dog,
    Cat
};

type KindMap = typeof kindMap;

function getAnimalClass<K extends keyof KindMap>(key: K): KindMap[K] {
    return kindMap[key];
}

// These types are inferred correctly
const DogClass = getAnimalClass('Dog'); 
const dog = new DogClass();

const CatClass = getAnimalClass('Cat');
const cat = new CatClass();
Run Code Online (Sandbox Code Playgroud)

在 TypeScript Playground 中尝试一下

我尝试getAnimal()使用映射类型来实现,但似乎遇到了错误的推理。但查找班级更容易。

内联查找getAnimalClass也适用于类型推断:

const dog = new kindMap['Dog']();
Run Code Online (Sandbox Code Playgroud)