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

时间:2019-07-18 23:35:21

标签: typescript

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

interface A {
  toRemove: string;
  key1: "this1";
  key2: number;
}
interface B {
  toRemove: string;
  key1: "this2";
  key3: string;
}

以及两个接口的结合:

type C = A|B;

我想做的是通过C从两个接口中删除toRemove键,就像这样:

type CC = Omit<A, "toRemove">|Omit<B, "toRemove">;

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

type CC = Omit<C, "toRemove">;

但是,不幸的是,CC的类型为Pick<A|B, "key1">,其中key1是两个界面中的键。

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

A1|A2|...|An

进入:

Omit<A1, K keyof A1>|Omit<A1, K keyof A2>|...|Omit<An, K keyof An>

我遇到了这个答案https://stackoverflow.com/a/56297816/6520174,我感到自己需要的部分在其中,但是我真的不明白该代码中发生了什么。

2 个答案:

答案 0 :(得分:3)

您想在整个联合体中分配 Omit。幸运的是,您可以使用distributive conditional types来实现:

type DistributiveOmit<T, K extends keyof any> = T extends any
  ? Omit<T, K>
  : never;

T extends any的构造看起来并没有做什么用,但是由于T是一个类型参数,因此它将条件类型分布在T的任何并集组成部分中。

让我们测试一下:

type CC = DistributiveOmit<C, "toRemove">;
// type CC = Pick<A, "key1" | "key2"> | Pick<B, "key1" | "key3">

您可以验证它是否等于您想要的CC类型。

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

Link to code

答案 1 :(得分:0)

另一种方法是:

export declare type Without<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type CC = Without<A, "toRemove">| Without<B, "toRemove">;