我在TypeScript中定义了以下enum:

enum Color{
    Red, Green
}

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

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

如何将该值转换为enum?


当前回答

在这个问题中有很多混合信息,所以让我们讨论TypeScript 2的整个实现。在Nick's Guide to Using Enums in Models with TypeScript中的x+。

本指南适用于:创建客户端代码的人,这些客户端代码从服务器获取一组已知字符串,这些字符串可以方便地在客户端建模为Enum。

定义枚举

让我们从枚举开始。它应该看起来像这样:

export enum IssueType {
  REPS = 'REPS',
  FETCH = 'FETCH',
  ACTION = 'ACTION',
  UNKNOWN = 'UNKNOWN',
}

这里需要注意两点:

我们显式地将这些声明为字符串支持的枚举情况,这允许我们用字符串来实例化它们,而不是其他一些不相关的数字。 我们添加了一个选项UNKNOWN,这个选项在我们的服务器模型上可能存在,也可能不存在。如果您愿意,可以将其处理为未定义,但我喜欢尽可能避免在类型上使用|未定义以简化处理。

使用UNKNOWN大小写的好处是,你可以在代码中非常明显地看到它,并为未知枚举大小写设置亮红色和闪烁的样式,这样你就知道你没有正确地处理某些事情。

解析枚举

您可以在另一个模型中使用这个枚举,或者单独使用这个枚举,但是您必须将字符串-y类型的枚举从JSON或XML (ha)解析为强类型的对应对象。当嵌入到另一个模型中时,这个解析器存在于类构造函数中。

parseIssueType(typeString: string): IssueType {
  const type = IssueType[typeString];
  if (type === undefined) {
    return IssueType.UNKNOWN;
  }

  return type;
}

如果枚举被正确地解析,它将以正确的类型结束。否则,它将是未定义的,您可以拦截它并返回UNKNOWN情况。如果您更喜欢使用undefined作为未知情况,则可以直接返回尝试的enum解析的任何结果。

从这里开始,只需要使用parse函数和使用新创建的强类型变量。

const strongIssueType: IssueType = parseIssueType('ACTION');
// IssueType.ACTION
const wrongIssueType: IssueType = parseIssueType('UNEXPECTED');
// IssueType.UNKNOWN

其他回答

对于Typescript >= 4,此代码工作:

enum Color{
    Red, Green
}

// Conversion :
var green= "Green";
var color : Color = green as unknown as Color; 

试试这个

var color: color =(任何颜色)["绿色];

这对于3.5.3版本来说很好

从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

如果你正在处理TypeScript 4.1+和字符串enum,并且你想要一个简单的具有编译时和运行时安全的字符串到enum转换器,下面的工作很好:

export const asEnum = <
  T extends { [key: string]: string },
  K extends keyof T & string
>(
  enumObject: T,
  value: `${T[K]}`
): T[K] => {
  if (Object.values(enumObject).includes(value)) {
    return (value as unknown) as T[K];
  } else {
    throw new Error('Value provided was not found in Enum');
  }
};

enum Test {
  hey = 'HEY',
}

const test1 = asEnum(Test, 'HEY');   // no complaints here
const test2 = asEnum(Test, 'HE');    // compile-time error
const test3 = asEnum(Test, 'HE' as any); // run-time error

如果TypeScript编译器知道变量的类型是字符串,那么这是可行的:

let colorName : string = "Green";
let color : Color = Color[colorName];

否则,你应该显式地将其转换为字符串(以避免编译器警告):

let colorName : any = "Green";
let color : Color = Color["" + colorName];

在运行时,两个解决方案都可以工作。