我在TypeScript中定义了以下enum:

enum Color{
    Red, Green
}

现在在我的函数中,我以字符串的形式接收颜色。我尝试了以下代码:

var green= "Green";
var color : Color = <Color>green; // Error: can't convert string to enum

如何将该值转换为enum?


当前回答

它在TypeScript 4.4.3 TS游乐场链接中为我工作。

  const stringToEnumValue = <T extends Record<string, string>, K extends keyof T>(
    enumObj: T,
    value: string,
  ): T[keyof T] | undefined =>
    enumObj[
      Object.keys(enumObj).filter(
        (k) => enumObj[k as K].toString() === value,
      )[0] as keyof typeof enumObj
    ];

  enum Color {
    Red = 'red',
    Green = 'green',
  }

  const result1 = stringToEnumValue(Color, 'yellow'); // undefined
  const result2 = stringToEnumValue(Color, 'green'); // Color.Green

  console.log(result1) // undefined = undefined
  console.log(result2) // Color.Green = "green"

其他回答

这些答案对我来说都太复杂了……

您可以简单地在枚举上创建一个解析函数,期望其中一个键作为参数。添加新颜色时,不需要进行其他更改

enum Color { red, green}

// Get the keys 'red' | 'green' (but not 'parse')
type ColorKey = keyof Omit<typeof Color, 'parse'>;

namespace Color {
  export function parse(colorName: ColorKey ) {
    return Color[colorName];
  }
}

// The key 'red' exists as an enum so no warning is given
Color.parse('red');  // == Colors.red

// Without the 'any' cast you would get a compile-time warning
// Because 'foo' is not one of the keys in the enum
Color.parse('foo' as any); // == undefined

// Creates warning:
// "Argument of type '"bar"' is not assignable to parameter of type '"red" | "green"'"
Color.parse('bar');

Typescript 3.9提案

enum Color{ RED, GREEN }

const color = 'RED' as Color;

容易peasy……柠檬捏的!

我正在寻找一个答案,可以从字符串中获得enum,但在我的情况下,enum值有不同的字符串值对应。OP有一个简单的枚举颜色,但我有一些不同的东西:

enum Gender {
  Male = 'Male',
  Female = 'Female',
  Other = 'Other',
  CantTell = "Can't tell"
}

当你试图解决性别问题时。CantTell与"Can't tell"字符串,它返回未定义的原始答案。

另一个答案

基本上,受到这个答案的强烈启发,我想出了另一个答案:

export const stringToEnumValue = <ET, T>(enumObj: ET, str: string): T =>
  (enumObj as any)[Object.keys(enumObj).filter(k => (enumObj as any)[k] === str)[0]];

笔记

我们使用筛选器的第一个结果,假设客户端从枚举中传递一个有效的字符串。如果不是这样,则返回undefined。 我们将enumObj转换为any,因为在TypeScript 3.0+(目前使用TypeScript 3.5)中,enumObj被解析为unknown。

使用实例

const cantTellStr = "Can't tell";

const cantTellEnumValue = stringToEnumValue<typeof Gender, Gender>(Gender, cantTellStr);
console.log(cantTellEnumValue); // Can't tell

注意:而且,正如有人在评论中指出的那样,我还想使用noImplicitAny。

更新版本

没有对任何正确类型的强制转换。

export const stringToEnumValue = <T, K extends keyof T>(enumObj: T, value: string): T[keyof T] | undefined =>
  enumObj[Object.keys(enumObj).filter((k) => enumObj[k as K].toString() === value)[0] as keyof typeof enumObj];

此外,更新版本有一个更简单的方法来调用它,更可读:

stringToEnumValue(Gender, "Can't tell");

从Typescript 2.1开始,enum中的字符串键都是强类型的。Keyof typeof用于获取可用字符串键的信息(1):

enum Color{
    Red, Green
}

let typedColor: Color = Color.Green;
let typedColorString: keyof typeof Color = "Green";

// Error "Black is not assignable ..." (indexing using Color["Black"] will return undefined runtime)
typedColorString = "Black";

// Error "Type 'string' is not assignable ..." (indexing works runtime)
let letColorString = "Red";
typedColorString = letColorString;

// Works fine
typedColorString = "Red";

// Works fine
const constColorString = "Red";
typedColorString = constColorString

// Works fine (thanks @SergeyT)
let letColorString = "Red";
typedColorString = letColorString as keyof typeof Color;

typedColor = Color[typedColorString];

https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types

我得到了它的工作使用以下代码。

var green= "Green";
var color : Color= <Color>Color[green];