如何在TypeScript中以枚举值为键创建可查询的嵌套字典?
TypeScript中用枚举值作为键创建嵌套字典的正确方式
我从其他文件导入了两个字符串枚举:
export enum Id { X = 'AA', Y = 'BB', Z = 'CC' }
export enum Place { us = 'USA', ind = 'INDIA', }
想要创建一个嵌套字典,要求既能通过valueThreshold[Id.X][Place.us]['foo']查询,也能在运行时通过valueThreshold['AA']['USA']['foo']查询。但直接按如下写法会报错Extra space after computed key 'Id.X',因为键被识别为字符串'Id.X'而非枚举实际值'AA':
// 错误写法 const valueThreshold = { Id.X : { Place.us : { 'foo' : 1, } }, Id.Y : { Place.us : { 'foo' : 6, } } }
正确实现方式
要让枚举值作为对象键,必须使用计算属性语法(将枚举值包裹在方括号[]内),这样TypeScript才会解析枚举的实际值作为键名。
1. 基础对象写法
import { Id, Place } from './your-enum-file'; const valueThreshold = { [Id.X]: { [Place.us]: { foo: 1, }, [Place.ind]: { foo: 1, }, }, [Id.Y]: { [Place.us]: { foo: 6, }, [Place.ind]: { foo: 4, }, }, };
2. 用Record类型约束结构(推荐)
如果需要强类型约束,可以嵌套使用Record来定义整个字典的类型:
// 最内层值结构 type ThresholdValue = { foo: number; }; // 中间层:Place枚举值映射到ThresholdValue type PlaceThreshold = Record<Place, ThresholdValue>; // 最外层:Id枚举值映射到PlaceThreshold type IdThreshold = Record<Id, PlaceThreshold>; // 带类型约束的变量定义 const valueThreshold: IdThreshold = { [Id.X]: { [Place.us]: { foo: 1 }, [Place.ind]: { foo: 1 }, }, [Id.Y]: { [Place.us]: { foo: 6 }, [Place.ind]: { foo: 4 }, }, // 必须补充Id.Z对应的结构,否则TypeScript会报错 [Id.Z]: { [Place.us]: { foo: 0 }, [Place.ind]: { foo: 0 }, }, };
3. 验证查询有效性
两种查询方式都能正常工作:
console.log(valueThreshold[Id.X][Place.us].foo); // 输出 1 console.log(valueThreshold['AA']['USA'].foo); // 输出 1
错误原因说明
直接写Id.X: {}时,JavaScript/TypeScript会把Id.X当作字符串字面量键,即键名是字符串"Id.X",而非枚举Id.X对应的实际值"AA"。只有[Id.X]这种计算属性语法,才会先求值Id.X得到"AA",再将其作为键名。
内容的提问来源于stack exchange,提问作者Abin K Paul
相关产品推荐
相关产品推荐

