如何在TypeScript中将字符串优化为“字符串枚举”?

时间:2019-08-08 11:57:10

标签: typescript

以一个简单的字符串枚举示例为例:

enum Animal {
  Dog = "Dog",
  Cat = "Cat",
  Sheep = 'Sheep'
}

const getNoise = (animal: Animal) => {
  switch (animal) {
    case Animal.Dog:
      return 'woof';
    case Animal.Cat:
      return 'meow';
    case Animal.Sheep:
      return 'baa';
  }
}

但是,假设我要创建另一个函数,该函数处理来自不受信任的用户输入的任意string。字符串应该应该是有效的Animal,但是它可能包含错字,因此我们需要在运行时对其进行验证。

这是一个例子:

const getNoiseUntrusted = (animal: string) => {
  if (!(animal in Animal)) {
    throw new Error('Animal not recognised');
  }

  return getNoise(animal); // TypeScript error
}

getNoise(animal)调用导致TypeScript错误:

Argument of type 'string' is not assignable to parameter of type 'Animal'.

如何获取TypeScript将该字符串转换为Animal

2 个答案:

答案 0 :(得分:2)

Animal["Dog"]将返回“狗”

Animal["Puppy"]将返回未定义


const getNoiseUntrusted = (animal: string) => {
    if(!Animal[animal]){
        throw new Error('Animal not recognised');
    }
}

答案 1 :(得分:1)

使用as进行铸造的工作原理:

const getNoiseUntrusted = (animal: string) => {
  if (!(animal in Animal)) {
    throw new Error('Animal not recognised');
  }
  return getNoise(animal as Animal);
}

您还可以在常规的getter中扩展该开关,因为您将对照特定枚举的值检查输入字符串。

const getNoiseUntrustedSwitch = (animal: string) => {
  switch (animal) {
    case Animal.Dog:
      return 'woof';
    case Animal.Cat:
      return 'meow';
    case Animal.Sheep:
      return 'baa';
    default: 
    throw new Error('Animal not recognised');
  }
}

最后,要基于@Daniel的答案,您还可以在访问枚举时进行强制转换:

const getNoiseUntrustedEnumAcess = (animal: string) => {
  if (!(animal in Animal)) {
    throw new Error('Animal not recognised');
  }
  return getNoise(Animal[animal as Animal]);
}

请参见TypeScript Playground

尽管请注意,这是区分大小写的,所以您可能需要在检查用户输入是否属于枚举之前对其稍做修改。