JS中字符串转枚举作为Map键失效问题及正确用法
枚举作为Map键的问题分析与解决
问题复现
以下代码执行后,转换得到的枚举值myColor无法在myMap中找到对应值,最终输出no mapVal found:
enum Color { RED = 0, GREEN } const myMap = new Map<Color, string>([ [Color.GREEN, "foo"], [Color.RED, "bar"] ]) const red_s = "RED" const myColor: Color = red_s as unknown as Color console.log(`myColor ${myColor}`) const mapVal = myMap.get(myColor) if (mapVal) { console.log(`mapVal ${mapVal}`) } else { console.log(`no mapVal found`) }
问题原因
TypeScript的数字枚举编译后会生成双向映射对象:既可以通过Color.RED拿到数字值0,也可以通过Color[0]拿到字符串"RED"。但你这里用"RED" as unknown as Color强制类型转换时,myColor的实际值是字符串"RED",而Map中存储的键是数字0(对应Color.RED)和1(对应Color.GREEN)。
Map的键是严格类型匹配的,字符串"RED"和数字0是完全不同的键,自然找不到对应值。
正确用法
1. 从字符串正确转换为数字枚举值
利用枚举的反向映射,把字符串转成对应的数字枚举值:
const red_s = "RED" // 通过keyof typeof Color确保字符串是枚举的合法键,再拿到对应数字值 const myColor: Color = Color[red_s as keyof typeof Color]
此时myColor的值为数字0,和Map中的键完全匹配,能正确获取到"bar"。
2. 改用字符串作为Map键(适合频繁处理字符串的场景)
如果业务中经常需要用字符串交互,可以直接把Map的键类型设为枚举的字符串键类型:
// 提取枚举的字符串键类型 type ColorKey = keyof typeof Color const myMap = new Map<ColorKey, string>([ ["GREEN", "foo"], ["RED", "bar"] ]) const red_s = "RED" const mapVal = myMap.get(red_s) // 直接用字符串查找,无需类型转换
3. 使用字符串枚举(推荐方案)
如果场景中经常需要在枚举和字符串之间转换,直接定义字符串枚举更直观,避免类型混淆:
enum Color { RED = "RED", GREEN = "GREEN" } const myMap = new Map<Color, string>([ [Color.GREEN, "foo"], [Color.RED, "bar"] ]) const red_s = "RED" const myColor: Color = red_s as Color // 值完全匹配,转换安全 const mapVal = myMap.get(myColor) // 可正确获取到"bar"
内容的提问来源于stack exchange,提问作者Juergen
相关产品推荐
相关产品推荐

