我在TypeScript中定义了以下enum:

enum Color{
    Red, Green
}

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

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

如何将该值转换为enum?


当前回答

打印稿1.倍

如果你确定输入字符串与Color enum完全匹配,那么使用:

const color: Color = (<any>Color)["Red"];

在输入字符串可能不匹配Enum的情况下,使用:

const mayBeColor: Color | undefined = (<any>Color)["WrongInput"];
if (mayBeColor !== undefined){
     // TypeScript will understand that mayBeColor is of type Color here
}

操场上


如果我们没有将enum转换为<任意>类型,那么TypeScript将显示错误:

元素隐式具有“any”类型,因为索引表达式不是类型“number”。

这意味着默认情况下,TypeScript Enum类型与数字索引一起工作。 let c = Color[0],但是没有像let c = Color["string"]这样的字符串索引。这是微软团队针对更一般问题对象字符串索引的一个已知限制。

2.打印稿x-4x

TypeScript移动到typeof概念的键。

如果some使用字符串值enum:

enum Color {
  Green = "GRN",
  Red = "RD"
}

然后有语言解决方案映射键值(颜色。Green -> "GRN")只是通过访问枚举成员,但没有简单的方法来做相反的事情("GRN" -> Color.Green)。通过使用反向映射:

请记住,字符串enum成员不会得到反向映射 根本就不存在。

一种可能的解决方案是手动检查值并将值强制转换为enum。请注意,它只适用于字符串枚举。

function enumFromStringValue<T> (enm: { [s: string]: T}, value: string): T | undefined {
  return (Object.values(enm) as unknown as string[]).includes(value)
    ? value as unknown as T
    : undefined;
}

enumFromStringValue(Color, "RD"); // Color.Red
enumFromStringValue(Color, "UNKNOWN"); // undefined
enumFromStringValue(Color, "Red"); // undefined

其他回答

从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

如果您正在使用名称空间来扩展枚举的功能,那么您还可以这样做

    enum Color {
        Red, Green
    }

    export namespace Color {
      export function getInstance(color: string) : Color {
        if(color == 'Red') {
          return Color.Red;
        } else if (color == 'Green') {
          return Color.Green;
        }
      }
    }

像这样使用它

  Color.getInstance('Red');

这个笔记与basarat的回答有关,而不是最初的问题。

我在自己的项目中遇到了一个奇怪的问题,编译器给出了一个大致相当于“不能将字符串转换为颜色”的错误,使用这段代码的等价物:

var colorId = myOtherObject.colorId; // value "Green";
var color: Color = <Color>Color[colorId]; // TSC error here: Cannot convert string to Color.

我发现编译器的类型推断变得混乱,它认为colorId是一个enum值,而不是一个ID。为了解决这个问题,我必须将ID转换为字符串:

var colorId = <string>myOtherObject.colorId; // Force string value here
var color: Color = Color[colorId]; // Fixes lookup here.

我不确定是什么导致了这个问题,但我会在这里留下这张便条,以防有人遇到和我一样的问题。

以这种方式创建的枚举被编译成一个对象,该对象同时存储正向(名称->值)和反向(值->名称)映射。从这张chrome devtools截图中我们可以看到:

下面是一个关于对偶映射如何工作以及如何从一个映射转换到另一个映射的例子:

enum Color{
    Red, Green
}
// To Number
var greenNr: number = Color['Green'];
console.log(greenNr); // logs 1

// To String
var greenString: string = Color[Color['Green']];  // or Color[Color[1]
console.log(greenString); // logs Green

// In your example

// recieve as Color.green instead of the string green
var green: string = Color[Color.Green];  

// obtain the enum number value which corresponds to the Color.green property
var color: Color = (<any>Color)[green];  

console.log(color); // logs 1

我还遇到了同样的编译器错误。只是Sly_cardinal方法的一个稍短的变种。

var color: Color = Color[<string>colorId];