如何用映射属性创建动态联合类型?TypeScript类型问题
解决方案:实现Type与对应属性的联合类型
完全可以实现你想要的效果,不需要修改Types和MappedValues这两个基础类型,只需要调整T1或T2的定义即可。
问题根源
你当前的T1采用交叉类型定义,当传入联合类型Types.Email | Types.Checkbox时,TypeScript会把交叉逻辑应用到整个联合,导致所有属性被合并到同一个类型中,而非拆分成独立的分支联合。
两种可行修改方案
方案一:利用分布式条件类型调整T1
给T1添加条件类型触发分布式类型分发,让联合类型的每个成员单独被处理,再将结果重新联合:
enum Types { Email = 'email', Checkbox = 'checkbox', } type MappedValues = { [Types.Email]: string; [Types.Checkbox]: boolean; }; // 添加条件类型触发分布式处理 type T1<T extends Types> = T extends Types ? { type: T } & { [key in T]: MappedValues[T] } : never; type T2 = T1<Types.Email | Types.Checkbox>;
方案二:通过映射类型直接生成联合
先定义单个Type对应的类型结构,再通过映射类型遍历Types的所有成员,最后取映射结果的所有值形成联合:
enum Types { Email = 'email', Checkbox = 'checkbox', } type MappedValues = { [Types.Email]: string; [Types.Checkbox]: boolean; }; // 定义单个Type对应的类型结构 type SingleField<T extends Types> = { type: T } & { [K in T]: MappedValues[K] }; // 遍历Types生成所有分支,再取值的联合 type T2 = { [K in Types]: SingleField<K> }[Types];
两种方案最终得到的T2类型都是你期望的:
{ type: 'email', email: string } | { type: 'checkbox', checkbox: boolean }
内容的提问来源于stack exchange,提问作者Martin Paucot
相关产品推荐
相关产品推荐

