这是可能的,我会尽力解释我的回答中的每个部分。
/** Returns keys in the left type which are not in the right type. */
type UniqueLeftKeys<T, U> = Exclude<keyof T, keyof U>
/** Returns keys in the right type which are not in the left type. */
type UniqueRightKeys<T, U> = Exclude<keyof U, keyof T>
/** Returns keys that exist in BOTH the left and right types. */
type CommonKeys<T, U> = keyof T & keyof U
type Merge<T, U> = {
[k in UniqueLeftKeys<T, U>]: T[k] // First part
} & {
[k in UniqueRightKeys<T, U>]: U[k] // Second part
} & {
[k in CommonKeys<T, U>]: T[k] | U[k] // Third part
}
秘密在于
Merge
类型,它由三部分组成。
第一部分将仅在LEFT类型中而不在RIGHT类型中的键添加到结果中。在您的示例中,属性
a, b, c
仅在接口
A
中,因此我们将这三个属性添加到我们的结果类型中。
第二部分获取仅在RIGHT类型中而不在LEFT类型中的键,并将这些属性添加到结果中。在您的示例中,右侧类型
B
不包含任何不在
A
中的键,因此我们不会将任何内容添加到结果类型中。
第三部分获取两种类型中都有的键,然后将这些键添加到结果类型中,其中这些键的类型是两种类型的联合。
现在您可以像这样使用此代码:
type C = Merge<A, B>
const c: C = {
a: false,
b: 1,
c: 'abc',
d: false
}
你可以轻松地通过内联这些额外的类型定义(UniqueLeftKeys、UniqueRightKeys和CommonKeys)来简化此代码,但是我在示例中保留了它们,因为这有助于解释每个步骤发生了什么。