[타입스크립트(TS)] Exclude와 Omit

Sam·2023년 3월 29일
0
post-thumbnail

exclude와 omit을 공부하다가 이 두 가지에 대해서 기록해놓지 않으면 다시 또 헷갈릴 것 같아서 포스팅을 하려고 한다.

타입스크립트의 exclude와 omit은 유틸리티 타입 (utility type)이다.

유틸리티 타입이란?

이미 정의해 놓은 타입을 변환하고 싶을 때 사용하면 좋은 타입을 말한다. 유틸리티 타입을 이용하면 기존의 타입을 이용해 새로운 타입을 만들 수 있다.

그럼 먼저 Omit에 대해 알아보자.


Omit<T, K>

설명에는 T 타입의 모든 프로퍼티 중 K를 제거하여 타입을 구성한다고 되어있다. 하지만 이 말이 어려울 수 있으니 코드로 살펴보도록 하자.

다음과 같은 객체가 있다고 가정해보자.

interface MyInterface {
  name: string;
  age: number;
  gender: string;
}

이제 Omit을 사용하여 "name" 프로퍼티를 제거해보자.

type MyNewInterface = Omit<MyInterface, "name">;

위 코드에서 Omit 타입은 첫 번째 인자로 객체 타입을 받고, 두 번째 인자로 제외할 프로퍼티의 이름을 받는다. 따라서, MyNewInterface 타입은 { age: number; gender: string; } 타입이 된다.

즉 , Omit은 객체에서 특정 프로퍼티를 제외하는데 사용한다.

Exclude도 분명히 "제외"하는 타입인데 무엇이 다를까?


Exclude<T, U>

설명에는 타입 T에서 U와 겹치는 타입을 제외한 타입을 구성한다고 되어있다. 이것도 역시 말이 어렵다. 직접 코드로 살펴보자.

다음과 같은 객체가 있다고 가정해보자.

type MyType = string | number | boolean;

Exclude를 통해 string과 number 타입을 제외한 새로운 타입을 만들어보자.

type MyNewType = Exclude<MyType, string | number>;

위 코드에서 Exclude 타입은 첫 번째 인자로 타입을 받고, 두 번째 인자로 제외할 타입을 받는다. 따라서, MyNewType 타입은 boolean 타입이 된다.

Exclude는 타입에서 특정 타입을 제외하는데 사용된다.

이 Exclude 타입이 이해가 되질 않아 직접 코드를 만들어봤다.

type Fruit = string | number | boolean;

type newFruit = Exclude<Fruit, string>

const fruit1: newFruit = "Kiwi";
const fruit2: newFruit = 1;

console.log(fruit1); // Error
console.log(fruit2);  // 1

Fruit 객체는 string, number, boolean을 받는다. 하지만 Exclude를 통해 string을 제외시켰다. 이러면 newFruit를 통해 만들어진 fruit1과 fruit2는 string 형식을 할당받지 못한다. 즉, console.log로 fruit2를 찍으면 정상적으로 1을 내보내지만, fruit1은 string 형식을 받았기 때문에 아래와 같은 error가 발생한다.

error TS2322: Type '"string"' is not assignable to type 'newFruit'.


마지막으로 Exclude에서 keyof를 사용하면 omit과 동일하게 동작이 가능하다.

interface Fruits {
  kiwi: string;
  orange: string;
  apple: string;
  banana: string;
  mango: string;
}

type Match = Exclude<keyof Fruits, "mango">;

사실상 위 코드는 omit를 사용하여 더 직관적으로 나타낼 수 있다.

interface Fruits {
  kiwi: string;
  orange: string;
  apple: string;
  banana: string;
  mango: string;
}

type Match = Omit<Fruits, "mango">;

두 가지를 구분해서 잘 사용해보도록 하자...

0개의 댓글