我认为以下版本的
MergeUnion<T>行为可能会符合您的要求:
type MergeUnion<T> = ( keyof T extends infer K ? [K] extends [keyof T] ? Pick<T, K> & { [P in Exclude<(T extends any ? keyof T : never), K>]?: T extends Partial<Record<P, infer V>> ? V : never } : never : never) extends infer U ? { [K in keyof U]: U[K] } : never;type C = MergeUnion<A | B>;// type C = { // something: string | string[]; // somethingElse?: number | undefined; }// }这与其他答案类似,因为它找到
T(称为
UnionKeys,定义为
T extends any ? keyof T :never)的所有组成部分的所有键的并集,并返回其中包含所有键的映射类型。不同之处在于,在这里我们还找到了
T(称为
IntersectKeys,定义为
keyofT)的所有成分的所有键的交集,并将这些键
T分为两组键。交集中的一个存在于每个成分中,因此我们可以做
Pick<T,IntesectKeys>以获取公共特性。其余的
Exclude<UnionKeys, IntersectKeys>在最终类型中是可选的。
更新2019-08-23:自TS3.5.1起,以下提到的错误似乎已修复
这很丑陋,如果我感觉更好的话,我会清理它。
问题在于,所有成分中出现的任何属性本身都是可选的时,仍然存在问题。Typescript中存在一个错误(从TS3.5开始),在中{a?:string} | {a?: number},该a
属性被视为 必需 属性,如{a: string | number |undefined},而如果任何组成部分将其视为可选,则将其视为可选是更正确的。该错误流到MergeUnion
:
type Oops = MergeUnion<{a?: string} | {a?: number}>// type Oops = { a: string | number | undefined; }我在那里没有一个很好的答案,甚至没有更复杂的答案,所以我将在这里停止。
也许这足以满足您的需求。或者,也许@ TitianCernicova-Dragomir的答案足以满足您的需求。希望这些答案对您有所帮助;祝好运!
链接到代码



