本文介绍了在 TypeScript 接口中使用字符串枚举值作为计算属性键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义一个函数,根据我给出的键返回不同类型的对象.它基本上就像这里在 createElement 函数

I want to define a function returns different type of object based on the key I give. It's basically like the trick used here in createElement function

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

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

However, instead of string literal, I want to use string enum type instead. So I wrote something like this

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()
  }
}

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

However, TypeScript seems doesn't like the way I put the enum Kind's value inside interface as the computed property, it complains

A computed property name in an interface must directly refer to a built-in symbol.

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

Here comes the question, I already have the constants defined in the enum, I don't like to use string literal, is there a way I can make this works? Which means use the Kind enum's value as the computed property key in the KindMap.

推荐答案

有时带有 keyof 的简单对象比 TypeScript 中的枚举更简单:

Sometimes a simple object with keyof is simpler than an enum in 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();

在 TypeScript Playground 中尝试

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

I tried to implement getAnimal() with mapped types but seemed to run into buggy inference. But looking up the class was easier.

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

Inlining the getAnimalClass lookup also works with type inference:

const dog = new kindMap['Dog']();

这篇关于在 TypeScript 接口中使用字符串枚举值作为计算属性键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!