TypeScript 如何基于元数据对象映射value为键、position为值的类型
正确实现方案
使用TypeScript 4.1+支持的*键重映射(Key Remapping)*语法即可实现一一对应的扁平映射,完整类型定义如下:
type IntegerEnumlikeHelper<T extends EnumlikeWithMetadata> = { // -readonly 用于移除as const带来的只读修饰,匹配示例输出 -readonly [K in keyof T as T[K]['value']]: T[K]['position'] };
测试你提供的常量对象:
const ENUMLIKE_WITH_METADATA = { a: { position: 1, value: 'str', }, b: { position: 2, value: 'ng', }, } as const; type transformedObject = IntegerEnumlikeHelper<typeof ENUMLIKE_WITH_METADATA>; // 输出类型完全匹配预期: // type transformedObject = { // str: 1; // ng: 2; // }
方案原理说明
你之前的两种方案问题根源:
- 第一种方案中,独立取值
T[keyof T]['value']和T[keyof T]['position']时,TS会丢失两个属性的对应关联,自动将所有value和所有position做笛卡尔积,导致每个键对应所有position的联合类型。 - 第二种方案的外层映射直接遍历原对象的顶层键,没有替换输出的键名,因此保留了
a、b作为外层键,形成嵌套结构。
键重映射语法[K in keyof T as 表达式]会在遍历原类型每个键的上下文中计算输出的键名,全程保留原条目value和position的对应关系,同时直接展平嵌套属性,刚好匹配需求。
如果不需要移除只读修饰(即允许输出属性带readonly),可以去掉-readonly前缀,直接写为[K in keyof T as T[K]['value']]: T[K]['position']即可。
注意:该实现假设原对象中所有条目的
value属性取值唯一,如果存在重复的value,后续条目会覆盖之前的映射结果。
内容的提问来源于stack exchange,提问作者kuskoman
相关产品推荐
相关产品推荐

