如何基于泛型联合类型有条件地为对象类型添加多个属性?
TypeScript条件添加多个对象属性的问题解析
先看给定的联合类型:
type Union = "a" | "b";
你已经知道可以通过单个条件映射给对象添加属性:
type Condition<T extends Union> = { [K in T extends "a" ? "someProp" : never]: string; } type Result = Condition<"a">; // 得到 { someProp: string; }
但当你尝试再加一个条件映射属性时就会报错,这是因为TypeScript不允许在同一个对象类型字面量里写多个映射类型(也就是[K in ...]这种语法)。映射类型是用来批量生成属性的语法,同一个对象字面量里只能存在一个,重复写就会触发语法错误。
下面是两种可行的解决方法:
方法一:用交叉类型合并多个映射类型
把每个条件对应的映射类型用&交叉起来,就能实现多个条件属性的添加:
type Condition<T extends Union> = { [K in T extends "a" ? "someProp" : never]: string } & { [K in T extends "a" ? "anotherProp" : never]: string }; // 当传入"a"时,得到包含两个属性的对象 type ResultA = Condition<"a">; // 等价于 { someProp: string; anotherProp: string; } // 传入"b"时,得到空对象 type ResultB = Condition<"b">; // type ResultB = {}
方法二:在单个映射里用联合属性名批量生成
如果多个属性的类型相同,可以把要添加的属性名做成联合类型,放在同一个映射里:
type Condition<T extends Union> = { [K in T extends "a" ? "someProp" | "anotherProp" : never]: string; }; type ResultA = Condition<"a">; // 直接得到 { someProp: string; anotherProp: string; } type ResultB = Condition<"b">; // type ResultB = {}
如果不同属性需要不同类型,方法一的交叉类型依然适用,比如:
type Condition<T extends Union> = { [K in T extends "a" ? "someProp" : never]: string } & { [K in T extends "a" ? "anotherProp" : never]: number }; type ResultA = Condition<"a">; // 得到 { someProp: string; anotherProp: number; }
内容的提问来源于stack exchange,提问作者Behemoth
相关产品推荐
相关产品推荐

