Вопрос:

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

typescript

36456 просмотра

7 ответа

8130 Репутация автора

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

Например у меня

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

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

type XY = { x: number, y: number };
Автор: Qwertiy Источник Размещён: 11.01.2018 09:18

Ответы (7)


17 плюса

8130 Репутация автора

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

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

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

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

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

Автор: Qwertiy Размещён: 11.01.2018 09:18

209 плюса

14932 Репутация автора

Решение

Для версий 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}
Автор: CRice Размещён: 11.01.2018 09:22

33 плюса

4174 Репутация автора

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

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

Применяя это к вашему примеру, тип XY может быть определен как:

type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>
Автор: Jason Hoetger Размещён: 05.04.2018 12:46

2 плюса

3372 Репутация автора

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

Автор: Krzysztof Kaczor Размещён: 04.05.2019 05:22

3 плюса

675 Репутация автора

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

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

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

Автор: GonchuB Размещён: 17.05.2019 08:09

0 плюса

9000 Репутация автора

В Typescript 3.5+ :

interface TypographyProps {
    variant: string
    fontSize: number
}

type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">
Автор: CorayThan Размещён: 24.07.2019 09:46

0 плюса

29 Репутация автора

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

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);
Автор: Andrew Zolotarev Размещён: 15.08.2019 07:33
Вопросы из категории :
32x32