유형에서 속성 제외


159

유형에서 단일 속성을 제외하고 싶습니다. 어떻게해야합니까?

예를 들어 나는

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

그리고 속성 z을 제외하고 싶습니다.

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

답변:


336

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 버전

Exclude2.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>(로 TUA와 키에 해당하는 유형으로) TA의 값으로 키 같은과 유형 : -keyed 3 종류의 교차 부분 집합 T, 유형 neverU와 유형 never모든 키. 그런 다음 인덱서를 통해 전달하여 올바른 값 유형을 얻습니다. 내가 맞아?
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

typescript 2.8에서는 새로운 내장 Exclude유형을 사용할 수 있습니다 . 2.8 릴리스 노트는 실제로는 '미리 정의 된 조건 유형 "이 언급 :

참고 : 제외 유형은 여기에 제안 된 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 이전의 훌륭한 솔루션입니다. typeoftypescript의 저평가 된 기능 중 하나입니다.
Jason Hoetger

1
영리한, 나는 그것을 좋아한다 :)! (2.8 이전)
maxime1992

결과에 유형 문자열이있는 z를 추가하는 방법
user602291

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

1
이것은 오래된 버전의 typescript에 적합합니다. 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)

추신 : 거기에 다른 유용한 것들이 많이 있습니다.)




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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.