Typescript字段映射类型错误校验时丢失字符串字面量类型问题
问题根因
这不是TypeScript的预期行为,问题出在你编写的FieldValuesOf类型工具没有保留原类型的联合分支互斥关系:
- 原
MyType是交叉联合结构{id: number} & (Type1 | Type2),两个分支互斥,TypeScript会对联合类型做多余属性校验,因此category: 'One'时不允许出现code字段。 - 你当前的
FieldValuesOf实现逻辑是直接遍历泛型T的所有属性,当T为联合类型时,keyof T会取所有联合分支的属性的并集(即id | category | status | code),映射后会把原本的联合结构压平为单个对象类型,完全丢失了分支间的互斥约束,因此不会触发多余属性校验。
修复方案
你需要利用TypeScript的分布式条件类型特性,让类型映射对联合的每个分支单独处理,处理完成后再合并为新的联合类型,修改后的FieldValuesOf实现如下:
export type FieldValuesOf<T> = // 触发分布式条件:对T的每个联合分支单独执行映射 T extends unknown ? { [key in keyof T]: Extract<FieldValueMappings, [T[key] extends string ? string : T[key], any]>[1] } : never;
修改后TransformedMyType会保留原有的联合分支结构:
// 实际等价于 type TransformedMyType = | { id: IntegerValue, category: StringValue, status: IntegerValue } | { id: IntegerValue, category: StringValue, code: StringValue }
此时你再声明同时包含category: {stringValue: 'One'}和code的const a时,TypeScript就会和原始类型的const b一样抛出多余属性的错误。
内容的提问来源于stack exchange,提问作者David Min
相关产品推荐
相关产品推荐

