梗概
在TypeScript中,数字枚举支持从值到键的双向获取,但字符串枚举不支持这种双向映射。这是由于编译器生成代码的差异造成的。
数字枚举的双向获取
数字枚举天然支持双向映射:
enum NumericEnum {
Up = 1,
Down,
Left,
Right
}
// 从键到值
console.log(NumericEnum.Up); // 输出: 1
console.log(NumericEnum.Down); // 输出: 2
// 从值到键
console.log(NumericEnum[1]); // 输出: "Up"
console.log(NumericEnum[2]); // 输出: "Down"字符串枚举的单向获取
字符串枚举只支持从键到值的单向映射:
enum StringEnum {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT"
}
// 从键到值
console.log(StringEnum.Up); // 输出: "UP"
// 从值到键 - 不支持
console.log(StringEnum["UP"]); // 输出: undefined实现原理
TypeScript在编译数字枚举时会生成额外的反向映射代码:
// 编译后的数字枚举
var NumericEnum;
(function (NumericEnum) {
NumericEnum[NumericEnum["Up"] = 1] = "Up";
NumericEnum[NumericEnum["Down"] = 2] = "Down";
// ...
})(NumericEnum || (NumericEnum = {}));这种双重赋值的方式创建了双向映射关系。
字符串枚举的双向映射解决方案
如果需要字符串枚举的双向映射,可以自己实现工具函数:
function getEnumKeyByValue<T extends Record<string, string>>(
enumObj: T,
value: string
): keyof T | undefined {
return Object.keys(enumObj).find(key => enumObj[key] === value) as keyof T | undefined;
}
console.log(getEnumKeyByValue(StringEnum, "UP")); // 输出: "Up"使用建议
- 需要双向映射时优先使用数字枚举
- 字符串枚举更适合需要明确语义的场景
- 避免在需要遍历的场景使用数字枚举(会产生双倍条目)
father:: ts 枚举 Enum 语法