TypeScript中如何将整数枚举用作对象类型的键?
整数枚举作为对象键的TypeScript问题解决
问题描述
尝试用整数枚举作为对象类型的键时,触发类型错误:
enum Enum { first = 1, second = 2, third = 3, } type EnumAsKey = { [key in Enum]: string; // 报错:Type 'Enum' is not assignable to type 'string' };
尝试其他写法也无法解决:
// 报错:索引签名参数类型必须是'string'、'number'、'symbol'或模板字面量类型 [key: Enum] // 同样报错:Type 'Enum' is not assignable to type 'string' [key: typeof Enum[keyof typeof Enum]]
疑问:整数枚举值是数字类型,为什么不能用作对象键?怎么实现用整数枚举值作为对象键的需求?
原因
TypeScript的映射类型([key in ...])要求键的类型必须是string、number、symbol或模板字面量类型的子类型。虽然整数枚举的值是数字,但枚举本身的类型是独立的Enum类型,并非直接等同于number,因此类型检查不通过。
另外,你尝试的[key: ...]是索引签名写法,它只能接受string、number、symbol这类宽泛类型,不能用枚举值的字面量联合类型,所以也会报错。
解决方案
方法1:用枚举值的数字字面量类型做映射键
通过typeof Enum[keyof typeof Enum]提取枚举值的数字字面量联合类型(这里是1 | 2 | 3),用它作为映射类型的键:
enum Enum { first = 1, second = 2, third = 3, } // 获取枚举值的数字类型:1 | 2 | 3 type EnumNumberValues = typeof Enum[keyof typeof Enum]; type EnumAsKey = { [key in EnumNumberValues]: string; }; // 合法使用示例 const obj: EnumAsKey = { 1: "第一个", 2: "第二个", 3: "第三个" };
方法2:用Record工具类型简化定义
TypeScript内置的Record工具类型可以快速生成键值对类型,结合枚举值类型使用更简洁:
enum Enum { first = 1, second = 2, third = 3, } type EnumNumberValues = typeof Enum[keyof typeof Enum]; type EnumAsKey = Record<EnumNumberValues, string>;
方法3:直接用数字字面量联合类型替代枚举(可选)
如果不需要枚举的语义,直接定义数字字面量联合类型更简单:
type Enum = 1 | 2 | 3; type EnumAsKey = { [key in Enum]: string; };
补充说明
字符串枚举可以直接用作映射键,是因为字符串枚举的类型本身就是字符串字面量的联合类型,天然符合映射类型的键要求;而整数枚举的类型是独立的枚举类型,需要显式提取其值类型才能使用。
内容的提问来源于stack exchange,提问作者BobtheMagicMoose
相关产品推荐
相关产品推荐

