TypeScript遍历枚举如何获取枚举类型值而非字符串类型
问题原因
Object.keys()、Object.values()这类原生对象方法的默认返回类型是string[]或any[],TypeScript不会自动推导其返回值属于枚举成员范围;同时TS的数字枚举会在编译时生成反向映射,例如示例中的MY_ENUM编译后实际结构为:
{ 0: "A", 1: "B", 2: "C", A: 0, B: 1, C: 2 }
直接遍历会同时拿到数字值和字符串键名,进一步导致类型不匹配。
解决方案
根据你实际需要的是枚举值还是枚举键名,选择对应写法即可:
场景1:需要获取枚举实际值(类型为MY_ENUM)
用Object.values()取值,先过滤掉反向映射生成的字符串键,通过类型守卫收窄类型后再遍历,无需额外断言也能保证类型安全:
enum MY_ENUM { A, B, C } type MY_TYPE = { field: MY_ENUM } const myArray: MY_TYPE[] = Object.values(MY_ENUM) // 过滤字符串项,保留数字类型的枚举值,同时收窄类型为MY_ENUM .filter((val): val is MY_ENUM => typeof val === 'number') .map(val => ({ field: val // 此时val类型为MY_ENUM,无类型错误 }))
场景2:需要获取枚举键名(类型为枚举的合法键)
如果你实际要存的是枚举的键名字符串,先把字段类型定义为枚举的键类型keyof typeof MY_ENUM,再过滤掉反向映射生成的数字键后遍历:
enum MY_ENUM { A, B, C } // 字段类型约束为MY_ENUM的合法键名 type MY_TYPE = { field: keyof typeof MY_ENUM } const myArray: MY_TYPE[] = Object.keys(MY_ENUM) // 过滤数字项,保留字符串类型的键名,收窄类型为枚举键类型 .filter((key): key is keyof typeof MY_ENUM => Number.isNaN(Number(key))) .map(key => ({ field: key // 此时key类型为"A"|"B"|"C",符合类型约束 }))
特殊情况:字符串枚举
字符串枚举没有反向映射逻辑,可以省略过滤步骤,直接做类型断言即可:
enum STR_ENUM { A = 'a', B = 'b', C = 'c' } type STR_TYPE = { field: STR_ENUM } const strArr: STR_TYPE[] = (Object.values(STR_ENUM) as STR_ENUM[]) .map(val => ({field: val}))
注意:不要跳过过滤步骤直接做类型断言,数字枚举的反向映射会导致最终数组混入不符合预期的项。
内容的提问来源于stack exchange,提问作者weilueluo
相关产品推荐
相关产品推荐

