TypeScript:如何利用索引签名简化动态键对象初始化?
解决方法
方法1:动态生成(推荐)
直接遍历枚举的所有值,自动构建productList,新增枚举成员时完全不用改初始化代码:
enum ProductType { PC = 'pc', LAPTOP = 'laptop', TV = 'tv' } interface Product { id: number; name: string; } const productList = Object.values(ProductType).reduce<{ [key in ProductType]: Product[] | undefined }>((acc, type) => { acc[type] = undefined; return acc; }, {} as { [key in ProductType]: Product[] | undefined });
原理很简单:Object.values(ProductType)会取出枚举的所有值,再用reduce把每个值作为键,对应值设为undefined,最后组装成符合类型要求的对象。以后加新的枚举成员,这段代码会自动把新成员也纳入初始化范围。
方法2:类型断言快速处理
如果只是不想手动写所有属性,也可以用类型断言跳过TypeScript的全属性检查:
let productList = {} as { [key in ProductType]: Product[] | undefined };
注意:这种方式下,productList初始是空对象,运行时访问新增枚举成员的属性会得到undefined(因为对象本身没这个键),但TypeScript类型系统会认为该属性存在。如果需要运行时对象确实包含所有枚举成员的键,优先用方法1。
方法3:封装通用工具函数
如果多个地方需要做类似的枚举初始化,可以封装个通用函数,以后直接复用:
function initEnumMap<T extends string | number>(enumObj: Record<string, T>): { [key in T]: undefined } { return Object.values(enumObj).reduce((acc, key) => { acc[key] = undefined; return acc; }, {} as { [key in T]: undefined }); } // 使用时直接调用 const productList = initEnumMap(ProductType) as { [key in ProductType]: Product[] | undefined };
这个函数适用于所有字符串或数字枚举,新增枚举成员时,只要传枚举对象进去就行,不用改函数本身。
内容的提问来源于stack exchange,提问作者Alvin
相关产品推荐
相关产品推荐

