首页 > 解决方案 > 在 TypeScript 中省略联合

问题描述

假设我有两个接口,X并且Y,它们都共享几个字段,但也有独立的字段:

interface X {
  abc: number;
  foo: number;
  bar: number;
}

interface Y {
  abc: number;
  foo: number;
  baz: number;
}

现在我创建了这些类型的联合:

type Z = X | Y;

结果类型是either X or Y,这很好。现在我使用以下命令删除一个常见字段Omit

type limitedZ = Omit<Z, 'foo'>;

我期望的是limitedZ具有以下形式:

{ abc: number, bar: number } | { abc: number, baz: number }

相反,独立的字段消失了,剩下的就是abc两者共享的字段。这是为什么?

这是一个演示链接

标签: typescripttypes

解决方案


为了使用工会完成您想要的事情,您可以这样做 - 但它没有按照您的期望做

type limitedZ = Omit<X, 'foo'> | Omit<Y, 'foo'>

由管道表示的联合几乎是一个 XOR,因此产生的类型必须是一个或另一个,即 X 或 Y,或者两种类型共有的键(所以不是真正的 xor)。这就是为什么你会得到意想不到的输出。如果您想简单地从这两种类型中删除 foo 这将起作用,但它不会创建 X 和 Y 的键合并的类型(看起来)。将比我更好地解释这部分。

我假设当您调用Omit<Z, 'foo'>typescript 时,会创建一个由两种类型的公共键形成的类型,例如 abc 和 foo,然后您删除 foo,因此只剩下 abc。

如果要创建具有 x 键和 y 键的类型,则需要执行类似的操作来创建交集类型。

type ThirdType = X & Y

这种类型现在具有 X 的所有键和 Y 的所有键。然后您可以限制它以删除 foo - 我认为这是您想要做的。

type FourthType = Omit<ThirdType, 'foo'>

或者在一行中完成所有操作

type limitedZ = Omit<X & Y, 'foo'>

这是否有助于解释发生了什么?


推荐阅读