打字稿-深度类型合并,包括可选属性

时间:2020-02-23 08:41:28

标签: typescript typescript-typings

到目前为止,我一直在使用交集(&)运算符合并两种对象类型。在某些情况下,交叉点将不起作用:

  • 两个对象中都存在object类型的属性,我想将它们合并
  • 两个对象中都存在一个可选属性。
  • 两个对象中都存在object类型的可选属性。

我正在寻找一种可以处理这些情况的通用药物。

This answer显示了如何隔离可选属性。

1 个答案:

答案 0 :(得分:1)

首先,感谢您提供类似问题的链接,我从那儿获得了实用程序类型-OptionalPropertyOf。在您的问题的解决方案之下

type OptionalPropertyOf<T> = Exclude<{
  [K in keyof T]: T extends Record<K, T[K]>
    ? never
    : K
}[keyof T], undefined>

type Merge<T1, T2,
    First = {
        [K in (keyof T1)]: K extends keyof T2 ? T1[K] | T2[K] : T1[K]
    }, OptionalSecond = {
        [K in Exclude<OptionalPropertyOf<T2>, keyof T1>]+?: T2[K]
    },
    NonOptionalSecond = {
        [K in Exclude<keyof T2, keyof First | keyof OptionalSecond>]: T2[K]
    }> = First & OptionalSecond & NonOptionalSecond

// Example
type A = {
    a: string,
    b?: number,
    f: number,
}
type B = {
    a: boolean,
    b? : string,
    c?: string,
    e: number
}
type C = Merge<A, B>
/* type C evaluated as
{
    a: string | boolean;
    b?: string | number | undefined;
    f: number;
    c?: string | undefined;
    e: number;
}

*/
const value: C = {
    a: true,
    e: 1,
    f: 2
}

我们做了三个步骤:

  • 类型First代表T1的所有字段,如果T2具有相同的字段,我们通过并集将其合并
  • 类型OptionalSecond表示在T2中是可选字段,但未在类型First中使用。我们在这里+?说,以便说这些字段在这里仍然是可选的
  • 类型NonOptionalSecond代表T2中的每个字段,此字段是附加字段,也是非可选字段

结果是我们同时拥有这两种类型的所有可选字段,而且在合并合并的情况下也可以通过并集进行。

相关问题