【问题标题】:Typescript - Deep type Merge, including optional propertiesTypescript - 深度类型合并,包括可选属性
【发布时间】:2020-02-24 02:46:41
【问题描述】:

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

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

我正在寻找一种也可以处理这些情况的通用产品。

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

【问题讨论】:

  • 我认为您只是在寻找联合运营商。 typescriptlang.org/docs/handbook/…
  • @ritaj,I 联合运算符不是合并运算符,而是 or 运算符。新类型将具有一种属性或另一种属性,但不能同时具有两者的属性。

标签: typescript typescript-typings


【解决方案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
}

我们做了三个步骤:

  • type First 表示T1 的所有字段 + 如果T2 有相同的字段我们通过联合合并它
  • type OptionalSecond 表示在T2 中是可选的但在First 类型中没有使用的字段。我们在这里说 +? 是为了说明这些字段在这里仍然是可选的
  • type NonOptionalSecond 表示T2 中的每个字段,这是附加的且非可选的

结果我们有两种类型的所有可选字段,在重复合并的情况下也是由联合完成的。

【讨论】:

  • 如果一个对象是可选的,而另一个对象是必需的,该怎么办?
猜你喜欢
  • 2017-09-10
  • 2021-01-18
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
  • 2020-09-14
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多