我在TypeScript中定义了以下enum:

enum Color{
    Red, Green
}

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

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

如何将该值转换为enum?


当前回答

TS 3.9.x

var color : Color = Color[green as unknown as keyof typeof Color];

其他回答

其他的变化可以是

const green= "Green";

const color : Color = Color[green] as Color;

枚举

enum MyEnum {
    First,
    Second,
    Three
}

示例使用

const parsed = Parser.parseEnum('FiRsT', MyEnum);
// parsed = MyEnum.First 

const parsedInvalid= Parser.parseEnum('other', MyEnum);
// parsedInvalid = undefined

忽略区分大小写的解析

class Parser {
    public static parseEnum<T>(value: string, enumType: T): T[keyof T] | undefined {
        if (!value) {
            return undefined;
        }

        for (const property in enumType) {
            const enumMember = enumType[property];
            if (typeof enumMember === 'string') {
                if (enumMember.toUpperCase() === value.toUpperCase()) {
                    const key = enumMember as string as keyof typeof enumType;
                    return enumType[key];
                }
            }
        }
        return undefined;
    }
}

提供的大多数答案都没有对Enums提供广泛的支持。允许OP请求只从字符串值中获取Enum,但是Enum也允许其他值。

interface StandardEnum<T> {
    [id: string]: T | string;
    [nu: number]: string;
}

/**
 * Converts the given representation of the value of one enumerated constant to an equivalent enumerated type.
 *
 * @param type - An enumeration type
 * @param value - A value to convert
 */
export const genericValueToEnum = <T, K extends StandardEnum<T>> (
    type: StandardEnum<T>,
    value: K[keyof K]
): T | undefined => {
    const keys = Object.keys(type); // ...but, not really.
    const values = Object.values(type)
        // Filter enum member names because `Object.values()` includes them.
        .filter((value) => !(
            typeof value === 'string' &&
            keys.includes(value) &&
            type[value] !== value
        ));

    return values.includes(value)
        ? value as unknown as T
        : undefined;
}

这将适用于所有枚举,无论它们多么复杂(或奇怪),只要它们没有被标记。

enum OddEnum {
    None = -1,
    No = 0,
    Yes = 1,
    Twenty = '20'
    Other = 'Other',
    MORE = 'More',
};

genericValueToEnum(OddEnum, -1); // => -1 as OddEnum;
genericValueToEnum(OddEnum, 'Other'); // => 'Other' as OddEnum;
genericValueToEnum(OddEnum, 'MORE'); // => undefined;

以这种方式创建的枚举被编译成一个对象,该对象同时存储正向(名称->值)和反向(值->名称)映射。从这张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

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

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

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

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

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