gpt4 book ai didi

typescript - TypeScript 中的交集和合并类型 `{ foo } & { bar }` 和 `{ foo, bar }` 之间的区别

转载 作者:行者123 更新时间:2023-12-03 14:47:47 25 4
gpt4 key购买 nike

考虑类型 FooBar1FooBar2定义如下:

type Foo = { foo: string };
type Bar = { bar: number };
type FooBar1 = Foo & Bar;
type FooBar2 = { foo: string; bar: number };

问: FooBar1 和有什么区别?和 FooBar2 ?

我的尝试/研究:
  • 它们可以双向分配给彼此!
    (手动检查并使用 tsd - see here )
  • 但是,它们彼此并不相同! (检查 tsd - see here )
  • VSCode 的智能感知不崩溃 { foo } & { bar }自动进入{ foo, bar } ,虽然它确实将其他复杂类型折叠为更简单的形式,例如 NonNullable<string | undefined>string :
  • // |------------------------------------------------------------|
    // | let x: { |
    // | a: string; |
    // | } & { |
    // | b: string; |
    // | } |
    // | -----------------------------------------------------------|
    // ^
    // | When hovering `x` here:
    // |
    let x: { a: string } & { b: string };

    编辑: Difference between extending and intersecting interfaces in TypeScript?已建议重复,但我不同意。我没有将交集与接口(interface)的扩展进行比较,而是将交集与另一种原始类型进行比较,不涉及接口(interface)或扩展。

    最佳答案

    在您的示例中,我们可以说 FooBar1FooBar2是平等的。我们确实可以证明:

    type Equals<A, B> =
    A extends B
    ? B extends A
    ? true
    : false
    : false

    type test0 = Equals<{a: 1} & {b: 2}, {a: 1, b: 2}> // true
    但是对于一般的答案,我们只能说它们并不总是相等的。为什么?因为交叉点可以解析为 never在某些情况下。如果 ts 发现一个交集是有效的,它会继续它,否则返回 never .
    import {O} from "ts-toolbelt"

    type O1 = {a: 1, b: 2}
    type O2 = {a: 1} & {b: 2} // intersects properly
    type O3 = {a: 1, b: 2} & {b: 3} // resolved to `never`

    type test0 = Equals<O1, O2>
    // true

    type test1 = O.Merge<{a: 1, b: 2}, {b: 3, c: 4}>
    // {a: 1, b: 2, c: 4}
    在这里输入 O3解析为 never因为 b3并且不能与 2 重叠.让我们更改我们的示例,以表明如果您有以下情况,则交叉路口将起作用:
    import {A} from "ts-toolbelt"

    type O4 = A.Compute<{a: 1, b: number} & {b: 2}> // {a: 1, b: 2}
    type O5 = A.Compute<{a: 1, b: 2} & {b: number}> // {a: 1, b: 2}
    这个例子还强调了交叉点是如何工作的——比如联合交叉点。 TypeScript 将遍历所有属性类型并将它们相交。我们已经强制 TypeScript 计算与 A.Compute 相交的结果。 .
    简而言之,如果 ts 不能与所有成员重叠,则该交集的乘积为 never .因此,它可能不适合作为合并工具:
    type O3 = {a: 1, b: 2} & {b: 3} // resolved to `never`
    所以请记住, &不是合并工具。 A & B仅等于 {...A, ...B}仅当它们具有不重叠的键时。如果需要合并类型,请使用 O.Merge .

    关于typescript - TypeScript 中的交集和合并类型 `{ foo } & { bar }` 和 `{ foo, bar }` 之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61330455/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com