TypeScript中如何将对象数组映射为字典并实现键自动补全
实现TypeScript字典键的自动补全方案
要满足你的所有需求,核心是利用TypeScript的字面量类型推导和工具类型,让编译器自动识别字典的具体键名,同时避免重复编写名称。以下是具体实现步骤:
步骤1:保留数据的原始类型信息
不要直接把data标注为Entry[](这会丢失name字段的具体字面量类型),改用as const让TypeScript推导每个条目的精确类型:
type Entry = { tld: string; name: string; population: number; }; // as const 强制TypeScript保留每个字段的字面量类型,不将name拓宽为string const data = [ {tld: 'de', name: 'Germany', population: 83623528}, {tld: 'at', name: 'Austria', population: 8975552}, {tld: 'ch', name: 'Switzerland', population: 8616571} ] as const;
步骤2:定义字典的精确类型
通过typeof和工具类型Record,提取data中所有name的字面量类型,生成字典的专属类型:
// 提取data数组中所有元素的name字段字面量类型 type CountryNames = typeof data[number]['name']; // 定义字典类型:键为具体国家名称,值为对应的数据条目类型 type CountryDictionary = Record<CountryNames, typeof data[number]>;
步骤3:生成字典并标注类型
Object.fromEntries默认返回宽泛的{[key: string]: ...}类型,因此需要将生成的字典断言为我们定义的精确类型:
const dictionary = Object.fromEntries( data.map(item => [item.name, item]) ) as CountryDictionary;
效果验证
完成后你会得到这些符合需求的结果:
- IDE会自动补全
dictionary.Germany、dictionary.Austria等具体键 dictionary.Germany的类型是精确的条目类型,包含所有字段的具体值dictionary.Germany和data[0]指向同一个对象,满足引用相等性
可选优化:兼顾类型校验与字面量保留
如果需要确保data的结构符合Entry类型,同时不丢失字面量信息,可以用satisfies关键字:
const data = [ {tld: 'de', name: 'Germany', population: 83623528}, {tld: 'at', name: 'Austria', population: 8975552}, {tld: 'ch', name: 'Switzerland', population: 8616571} ] as const satisfies readonly Entry[];
satisfies会检查data是否符合Entry[]的结构,但不会覆盖TypeScript对字面量类型的推导,平衡了类型安全与精确性。
内容的提问来源于stack exchange,提问作者luckydonald
相关产品推荐
相关产品推荐

