从类型中排除属性

时间:2018-01-11 21:18:44

标签: typescript

我想从类型中排除单个属性。我怎么能这样做?

例如我有

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

我想排除属性z以获取

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

8 个答案:

答案 0 :(得分:159)

对于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

您不能在2.8以下版本中使用Exclude类型,但您可以为其创建替代品,以便使用与上述相同的定义。但是,此替换只适用于字符串类型,因此它不如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}

答案 1 :(得分:33)

使用typescript 2.8,您可以使用新的内置Exclude类型。 accessors实际上在“预定义条件类型”一节中提到了这一点:

  

注意:Exclude类型是Diff类型的正确实现   这里建议。 [...]我们没有包括Omit类型,因为   它简单地写成Pick<T, Exclude<keyof T, K>>

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

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

答案 2 :(得分:16)

我发现as shown in the JavaDoc声明了一些变量并使用spread运算符来推断类型:

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

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

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

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

答案 3 :(得分:10)

忽略

单个属性

type T1 = Omit<XYZ, "z"> // { x: number; y: number; }

多个属性

type T2 = Omit<XYZ, "y" | "z"> // { x: number; } 

有条件的属性

例如所有字符串类型:
type Keys_StringExcluded<T> = { [K in keyof T]: T[K] extends string ? never : K }[keyof T]

type XYZ = { x: number; y: string; z: number; }
type T3a = Pick<XYZ, Keys_StringExcluded<XYZ>> // { x: number; z: number; }
带有TS 4.1映射类型as子句的简短版本:
type T3b = { [K in keyof XYZ as XYZ[K] extends string ? never : K]: XYZ[K] } 
// { x: number; z: number; }

通过string模式的属性

例如排除吸气剂(带有“ get”字符串前缀的道具)
type OmitGet<T> = { [K in keyof T as K extends `get${infer _}` ? never : K]: T[K] }

type XYZ2 = { getA: number; b: string; getC: boolean; }
type T4 = OmitGet<XYZ2> //  { b: string; }

注意:TS 4.1支持template literal types以上的版本


Playground sample

答案 4 :(得分:2)

如果您想使用库,请使用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:您会在那找到很多其他有用的东西;)

答案 5 :(得分:2)

打字稿3.5

从Typescript 3.5开始,将包括“省略”帮助器:TypeScript 3.5 RC - The Omit Helper Type

您可以直接使用它,并且在更新时应该删除自己的Omit助手定义。

答案 6 :(得分:0)

Typescript 3.5+中:

interface TypographyProps {
    variant: string
    fontSize: number
}

type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">

答案 7 :(得分:0)

我喜欢这样:

interface XYZ {
  x: number;
  y: number;
  z: number;
}
const a:XYZ = {x:1, y:2, z:3};
const { x, y, ...last } = a;
const { z, ...firstTwo} = a;
console.log(firstTwo, last);
相关问题