Исключить свойство из типа

Я хотел бы исключить одно свойство из этого типа. Как я могу это сделать?

Например, у меня есть

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

И я хочу исключить свойство z чтобы получить

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

Ответ 1

Для версий TypeScript версии 3.5 или выше

В TypeScript 3.5 тип Omit был добавлен в стандартную библиотеку. Ниже приведены примеры использования.

Для версий TypeScript ниже 3.5

В TypeScript 2.8 тип Exclude был добавлен в стандартную библиотеку, что позволяет писать тип пропуска просто как:

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

Для версий TypeScript ниже 2.8

Вы не можете использовать тип 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}

Ответ 2

С помощью машинописного текста 2.8 вы можете использовать новый встроенный тип Exclude. В примечаниях к выпуску 2.8 упоминается об этом в разделе "Предопределенные условные типы":

Примечание. Тип Exclude - это правильная реализация предложенного здесь типа Diff. [...] Мы не включили тип Omit, потому что он тривиально написан как Pick<T, Exclude<keyof T, K>>.

Применив это к вашему примеру, введите значение XY:

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

Ответ 3

Я нашел решение с объявлением некоторых переменных и использованием оператора спреда для вывода типа:

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

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

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

Он работает, но я был бы рад увидеть лучшее решение.

Ответ 4

Машинопись 3,5

Начиная с Typescript 3.5, будет включен помощник Omit: TypeScript 3.5 RC - Тип помощника Omit

Вы можете использовать его напрямую, и вы должны удалить свое собственное определение помощника Omit при обновлении.

Ответ 5

Если вы предпочитаете использовать библиотеку, используйте 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: там вы найдете много других полезных вещей;)

Ответ 6

В машинописи 3. 5+:

interface TypographyProps {
    variant: string
    fontSize: number
}

type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">

Ответ 7

Мне так нравится:

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);