创建TypeScript映射类型时如何引用索引类型实现联合类型按name属性映射
可行实现方案
你想要的功能可以通过TS内置的Extract工具类型实现,正确写法如下:
type TypeMap = { [K in AllTypes['name']]: Extract<AllTypes, { name: K }> };
实现原理
- 映射类型的键遍历的是
AllTypes['name'],也就是所有name属性的字面量联合:"apple" | "banana" | "cherry" - 每遍历到一个键
K,就用Extract从AllTypes联合类型中,筛选出name属性等于K的成员类型,作为当前键对应的值类型。
你可以通过以下代码验证效果:
// 验证类型匹配符合预期 type TestApple = TypeMap['apple'] // 等价于原Apple类型 type TestBanana = TypeMap['banana'] // 等价于原Banana类型 type TestCherry = TypeMap['cherry'] // 等价于原Cherry类型
通用封装
如果需要复用这个逻辑处理其他类似的联合类型,可以封装成通用工具类型:
/** * 把带标识字段的联合类型,映射为「标识值-对应类型」的字典类型 * @param T 原始联合类型,必须包含指定的标识字段 * @param Key 标识字段的名称,默认为'name' */ type UnionToMap<T extends Record<Key, PropertyKey>, Key extends keyof T = 'name'> = { [K in T[Key]]: Extract<T, Record<Key, K>> } // 使用时只需传入联合类型即可 type TypeMap = UnionToMap<AllTypes> // 如果联合类型的标识字段不是name,比如是id,只需指定第二个参数: // type TypeMap = UnionToMap<AllTypes, 'id'>
内容的提问来源于stack exchange,提问作者dwjohnston
相关产品推荐
相关产品推荐

