TypeScript如何将等长键值元组/联合转为一一对应的Record交叉类型
实现方案
直接使用等长元组作为输入即可实现任意长度的一一对应类型,元组天然带顺序索引,能严格保证键值的对应关系,实现代码如下:
type OneToOne< K extends (string | number | symbol)[], V extends unknown[], // 长度守卫:传入不等长元组时会直接触发类型错误 _LengthCheck extends K['length'] = V['length'] > = K['length'] extends V['length'] // 遍历元组索引,将对应位置的键值映射为对象属性 ? { [Index in keyof K as K[Index]]: V[Index & keyof V] } : never
该实现最终生成的对象类型,和你需求里写的多个Record交叉的效果完全一致,使用体验更友好。
使用示例
针对你给出的测试用例,直接调用即可得到符合预期的类型:
type Keys = ['North', 'East', 'South', 'West']; type Values = ['n', 'e', 's', 'w']; // 最终得到的DirectionMap类型等价于 { North: 'n', East: 'e', South: 's', West: 'w' } type DirectionMap = OneToOne<Keys, Values>; // 类型校验生效,属性值写错、漏写属性都会触发类型报错 const directionMap: DirectionMap = { North: 'n', East: 'e', South: 's', West: 'w' };
说明
- 不建议使用联合类型作为输入:联合类型本身没有顺序定义,无法保证键值的一一对应关系,元组方案的可控性和可靠性更高。
- 该实现支持任意长度的等长元组输入,不需要提前写死索引位置。
内容的提问来源于stack exchange,提问作者viell
相关产品推荐
相关产品推荐

