새소식

반응형
Study

TypeScript - 유틸리티 타입(Utility types) 사용

  • -
반응형

타입스크립트에서는 Type Transformation을 유연하게 도와 주는 여러 유틸리티 타입을 제공하고 있습니다. (TypeScript Utility Types) 그 중에 실무에서 유용한 몇가지 타입을 알아보겠습니다.

 

타입스크립트에서는 조건부 형식으로 타입을 정의 할 수 있습니다.

T extends U ? X : Y

위와 같은 형태를 취하는데 조건식 결과에 따라 X가 될 수도 Y 가 될 수도 있습니다.

타입스크립트는 용도에 맞게 조건부 타입을 활용한 새로운 타입들을 미리 정의해두고 이것을 "Predefined conditional types" 라고 하며 그 중 하나가 Exculude  입니다.

Exclude<T, U>

Exclude 타입은 2개의 제네릭 타입을 받을 수 있으며, 첫번재 제네릭 타입 T 중 두번째 제네릭 타입 U와 겹치는 타입을 제외한 타입을 반환합니다.

type Exclude<T, U> = T extends U ? never : T;

즉 T에 오는 타입들 중 U에 오는 것들은 제외하겠다는 의미가 됩니다.

type OnlyNumber = Exclude<string|number, string>;
// OnlyNumber는 number 타입이 됩니다.

다시 말해 두번째 제네릭 타입 U에 대해 첫번째 제네릭 타입 T가 할당 가능한 타입인지 판단하고, 할당 가능한 타입을 제외한 나머지 타입들을 이용하여 타입을 정의 합니다.

그래서 Exculude는 보통 어떤 유니온 타입에서 특정한 타입들을 제외하려고 할 때 사용합니다.

 

아래와 같은 사용도 가능합니다.

interface Player {
  name: string;
  rank: string;
  contry: string;
  playTime: number;
}

type noNamePlayer = Exclude<keyof Player, "name">;
// type noNamePlayer = "rank" | "contry" | "playTime" 와 같다.

keyof Player 를 통해서 Player 객체의 key 값만을 모으고 exclude를 사용하여 제외할 값을(name) 지정 할 수 있습니다.

 

Pick <T, K>

T 타입으로 부터 K 프로퍼티만 추출 합니다.

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

Pick은 어떤 정의된 객체 형태의 타입에서 특정한 프로퍼티들만 골라서 새로운 타입으로 만들어 줍니다.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, "title" | "completed">;
// TodoPreview 타입은 Todo 타입의 프로퍼티들 중에서 title, completed만 골라낸 타입이 됩니다.

 

Omit <T,  K>

Omit 타입은 두개의 제네릭 타입을 받으며 T에서 모든 프로퍼티를 선택한 다음 K를 제거한 타입을 구성합니다.

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

Omit은 어떤 정의된 객체 형태의 타입에서 특정한 프로퍼티들을 제외시켜 줍니다.

interface Match {
  accountNo: number;
  matchRank: number;
  name: string;
  age: number;
}

type PersonInfo = Omit<Match, "accountNo" | "matchRank">;
// PersonInfo 타입은 Match 타입의 프로퍼티들중 accountNo,matchRank를 제외한 나머지로 이루어지게 됩니다.

Partial<T>

Partial은 제네릭 타입 T에 대해서 모든 프로퍼티들을 Optional하게 변경합니다.

type Partial<T> = {    
  [P in keyof T]?: T[P];
};

제네릭 타입의 프로퍼티들에 대해 기존의 타입은 유지하되, 각각의 프로퍼티들을 optional 타입으로 변경해 줍니다.

interface Product {
    id: number;
    seller: number;
    category: number;
    name: string;
    price: string;
}

type SearchProduct = Partial<Product>;

/*
type SearchProduct {
    id?: number;
    seller?: number;
    category?: number;
    name?: string;
    price?: string;
}
*/

필수 타입과 optional 타입을 구분해서 사용해야 하는 경우 아래와 같이 쓸 수도 있습니다.

type UserInformation = RequiredUserInformation & Partial<OptionalUserInformation>;

interface RequiredUserInformation {
  id: string;
  uid: string;
  name: string;
}

interface OptionalUserInformation {
  age: number;
  profile: string;
  phone: string;
}

 

위의 유틸리티 타입들을 간단하게 정리하면 

  • Exculde: 어떤 타입(보통 유니온)에서 특정한 타입들을 제외시켜 정의하고 싶을 때
  • Pick: 정의된 객체 유형의 타입에서 특정 프로퍼티를 선택한 새로운 타입을 정의 하고 싶을 때
  • Omit: 정의된 객체 유형의 타입에서 특정 프로퍼티를 제외한 타입을 정의하고 싶을 때
  • Partial: 모든 프로퍼티를 Optional 하게 변경하고 싶을 때

사용합니다.

 

Reference

https://chanhuiseok.github.io/posts/ts-3/

https://jaehoney.tistory.com/105

https://velog.io/@ggong/Typescript%EC%9D%98-%EC%9C%A0%ED%8B%B8%EB%A6%AC%ED%8B%B0-%ED%83%80%EC%9E%85-1-Record-Extract-Pick

https://velog.io/@ggong/Typescript%EC%9D%98-%EC%9C%A0%ED%8B%B8%EB%A6%AC%ED%8B%B0-%ED%83%80%EC%9E%85-2-Partial-Required-ReadOnly-Omit-NonNullable-ReturnType

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.