打字稿:省略联合中所有接口的属性,但保留联合结构

Lui*_*ais 19 typescript

我是打字稿的新手,我定义了一些接口,如下所示:

interface A {
  toRemove: string;
  key1: "this1";
  key2: number;
}
interface B {
  toRemove: string;
  key1: "this2";
  key3: string;
}
Run Code Online (Sandbox Code Playgroud)

以及两个接口的联合:

type C = A|B;
Run Code Online (Sandbox Code Playgroud)

我想要做的是toRemove通过 C 从两个接口中删除密钥,如下所示:

type CC = Omit<A, "toRemove">|Omit<B, "toRemove">;
Run Code Online (Sandbox Code Playgroud)

但不必从两个接口中省略密钥。这将是理想的:

type CC = Omit<C, "toRemove">;
Run Code Online (Sandbox Code Playgroud)

但是,不幸的是,CC将是 type Pick<A|B, "key1">key1两个接口中都存在的键在哪里。

从本质上讲,我想要实现的是一种要转换的“功能”:

A1|A2|...|An
Run Code Online (Sandbox Code Playgroud)

进入:

Omit<A1, K keyof A1>|Omit<A1, K keyof A2>|...|Omit<An, K keyof An>
Run Code Online (Sandbox Code Playgroud)

我遇到了这个答案/sf/answers/3940847151/,我有一种感觉,我需要的部分就在那里,但我真的不明白该代码中发生了什么。

jca*_*alz 34

您想在整个联合中分发Omit。幸运的是,您可以使用分布式条件类型来实现这一点:

type DistributiveOmit<T, K extends keyof any> = T extends any
  ? Omit<T, K>
  : never;
Run Code Online (Sandbox Code Playgroud)

T extends any构造看起来并没有做太多事情,但由于T是一个类型参数,它将条件类型分布在T.

让我们测试一下:

type CC = DistributiveOmit<C, "toRemove">;
// type CC = Pick<A, "key1" | "key2"> | Pick<B, "key1" | "key3">
Run Code Online (Sandbox Code Playgroud)

您可以验证这是否与CC您想要的类型等效。

希望有所帮助;祝你好运!

代码链接

  • 我已将编辑器设置为在使用任何类型时警告我,并且我相信在这种情况下可以删除它们。可以将“K extends keyof any”替换为“K extends keyof T”,并且不能将“T extends any”替换为“T extends T”,因为它将解析为“A extends T”?... | B 延伸 T?...` (3认同)