TypeScript能否根据键推断Map的值类型?如何正确类型化异构Map
解决方案
可以通过定义精确的键值映射类型,并结合类型断言让迭代器返回带键值对应关系的条目,实现 TypeScript 对值类型的正确推断:
1. 定义键值对应关系
先明确每个键对应的具体类型:
type KeyValuePairs = { A: boolean; B: boolean; X: string[]; Y: string[]; };
2. 定义自定义 Map 类型
基于上述键值对定义 Map 类型,确保键只能是KeyValuePairs的键,值是对应类型的联合:
type CustomType = Map<keyof KeyValuePairs, KeyValuePairs[keyof KeyValuePairs]>;
3. 遍历前断言迭代器类型
将 Map 的条目迭代器断言为带有精确键值对应关系的联合类型,这样 switch 判断键时,TypeScript 能自动推断对应的值类型:
// 初始化符合类型的 Map 实例 const MyMap: CustomType = new Map([ ['A', true], ['B', false], ['X', ['foo']], ['Y', ['bar']] ]); // 定义精确的键值条目联合类型 type CustomEntry = { [K in keyof KeyValuePairs]: [K, KeyValuePairs[K]] }[keyof KeyValuePairs]; // 遍历并断言迭代器类型 for (const [key, value] of MyMap.entries() as Iterable<CustomEntry>) { switch(key) { case 'A': case 'B': // TypeScript 自动推断 value 为 boolean console.log(value === true); // 无类型错误 break; case 'X': case 'Y': // TypeScript 自动推断 value 为 string[] console.log(value.length); // 无类型错误 break; } }
原理说明
{ [K in keyof KeyValuePairs]: [K, KeyValuePairs[K]] }生成一个对象,每个键对应[键, 值类型]的元组;- 通过
[keyof KeyValuePairs]提取该对象的所有值,得到['A', boolean] | ['B', boolean] | ['X', string[]] | ['Y', string[]]的联合类型; - 将迭代器断言为这个联合类型后,TypeScript 就能通过
key的字面量类型,精准推断出对应的value类型。
内容的提问来源于stack exchange,提问作者apokaliptis
相关产品推荐
相关产品推荐

