从类型中排除属性


155

我想从类型中排除单个属性。我怎样才能做到这一点?

例如我有

interface XYZ {
  x: number;
  y: number;
  z: number;
}

我想排除财产z以获得

type XY = { x: number, y: number };

Answers:


332

适用于3.5以上的TypeScript版本

在TypeScript 3.5中,Omit类型已添加到标准库中。请参阅以下示例以了解如何使用它。

对于3.5以下的TypeScript版本

在TypeScript 2.8中,该Exclude类型已添加到标准库中,该标准库允许将省略类型写为:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

对于2.8以下的TypeScript版本

您不能Exclude在2.8以下的版本中使用该类型,但可以使用它来替代它,以便使用与上述相同的定义。但是,此替换仅适用于字符串类型,因此其功能不如Exclude

// Functionally the same as Exclude, but for strings only.
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T]
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>

并使用该类型的示例:

interface Test {
    a: string;
    b: number;
    c: boolean;
}

// Omit a single property:
type OmitA = Omit<Test, "a">; // Equivalent to: {b: number, c: boolean}

// Or, to omit multiple properties:
type OmitAB = Omit<Test, "a"|"b">; // Equivalent to: {c: boolean}

大!您要声明Diff<T, U>(具有TU作为键可用的类型)作为T3个类型的交集的-keyed子集:带key的T类型与neverfor 的值相同,带for的U类型和带neverfor所有键的type 。然后,将其传递给索引器以获取正确的值类型。我对吗?
Qwertiy

5
是的 但这确实有一个缺点。例如,Omit<{a?: string, b?: boolean}, "b">结果中的{a: string | undefined},仍会接受undefined作为值,但会丢失上的可选修饰符a。:(
CRice

真可悲。.使用声明和传播有趣的方式保留可选修饰符...还有其他保留方法吗?
Qwertiy

1
@Qwertiy它有效!非常感谢!我编辑了帖子。但是我不知道有什么区别,因为Pick据我所知,它实际上与类型定义相同。
CRice

3
请注意,对于TS 3.5,标准库的定义Omit与此处给出的定义不同。在stdlib中,它是type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;更改,尽管很小,但引起了一些争论,因此请注意区别。
CRice

41

使用打字稿2.8,您可以使用新的内置Exclude类型。在2.8版本说明实际上在节“预定义条件类型”提到这一点:

注意:Exclude类型是此处建议的Diff类型的正确实现。[...]我们没有包含Omit类型,因为它的形式很简单Pick<T, Exclude<keyof T, K>>

将此应用于您的示例,XY类型可以定义为:

type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>

19

我找到了声明一些变量并使用传播运算符来推断类型的解决方案

interface XYZ {
  x: number;
  y: number;
  z: number;
}

declare var { z, ...xy }: XYZ;

type XY = typeof xy; // { x: number; y: number; }

它有效,但是我很高兴看到更好的解决方案。


3
这是一个很棒的2.8之前的解决方案。typeof是Typescript较不被重视的功能之一。
杰森·霍特杰

1
聪明,我喜欢它:)!(适用于2.8之前的版本)
maxime1992年

我如何在结果中添加类型为字符串的z
user602291 '18

@ user602291 ,type Smth = XY & { z: string };
Qwertiy

1
这是旧版本打字稿的理想选择。我无法获得胜任的2.3版答案,但是这个效果很好。
k0pernikus

6

如果您更喜欢使用库,请使用ts-essentials

import { Omit } from "ts-essentials";

type ComplexObject = {
  simple: number;
  nested: {
    a: string;
    array: [{ bar: number }];
  };
};

type SimplifiedComplexObject = Omit<ComplexObject, "nested">;

// Result:
// {
//  simple: number
// }

// if you want to Omit multiple properties just use union type:
type SimplifiedComplexObject = Omit<ComplexObject, "nested" | "simple">;

// Result:
// { } (empty type)

PS:您会在这里找到许多其他有用的东西;)



4

打字稿3.5+中

interface TypographyProps {
    variant: string
    fontSize: number
}

type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.