Post

[TypeScript] 유틸리티 타입

[TypeScript] 유틸리티 타입

데브타스

유틸리티 타입

  • 타입스크립트에서 어떤 목적을 달성하기 위한 기능을 구현한 커스텀 타입을 의미

Partial< T >

  • 주어진 타입 T의 모든 속성을 선택적으로 만드는 유틸리티 타입
  • 다음과 같이, 하나의 인터페이스에 존재하는 것을
    따로 인터페이스로 구현해서 사용해야하는 번거로움 존재.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
      interface User {
        name: string;
        age: number;
      }
      interface GuestType1 {
        name: string;
      }
        
      interface GuestType2 {
        age: number;
      }
        
      const user1: User = {
        name: "jaegeon",
        age: 26,
      };
      const guest1: GuestType1 = {
        name: "jaegeon",
      };
      const guest2: GuestType2 = {
        age: 26,
      };
    
  • 따라서, Partial< T >를 사용하여, 인터페이스의 일부를 이용할 수 있도록 한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
      interface User {
        name: string;
        age: number;
      }
        
      const user1: User = {
        name: "jaegeon",
        age: 26,
      };
      const guest1: Partial<User> = {
        name: "jaegeon",
      };
      const guest2: Partial<User> = {
        age: 26,
      };
    
  • 타입 별칭에서도 동일하게 사용 가능하다.
  • 코드 수를 줄일 수 있고, 유지보수에서 용이하다.

Required< T >

  • 주어진 타입 T의 모든 속성을 필수 속성으로 만드는 유틸리티 타입
  • 다음과 같이, 옵셔널 프로퍼티가 있는 선택 속성의 구조 존재
  • 해당 타입을 필수로 받아야하는 별도의 구조 필요 시, 사용
  • Partial< T >를 사용하여, 옵셔널 프로퍼티의 속성도 필수로 받는다!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
      type User = {
        name: string;
        age?: number;
        gender: string;
      };
        
      const normalUser: User = {
        name: "jaegeon",
        gender: "male",
      };
      const adultUser: Required<User> = {
        name: "jaegeon",
        age: 26,
        gender: "male",
      };
    

Readonly< T >

  • 주어진 타입 T의 모든 속성을 읽기 전용으로 만드는 유틸리티 타입
  • 해당 유틸리티를 사용하여, 초기값이 수정이 안되도록 막는다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
      type User = {
        name: string;
        age?: number;
        gender: string;
      };
        
      const premiumUser: Readonly<User> = {
        name: "jaegeon",
        age: 26,
        gender: "male",
      };
      // premiumUser.name = "john"; (수정 불가)
    

Pick< T, K >

  • 객체로 주어진 타입 T의 모든 속성에서
    선택한 속성 K만 추출하여 만드는 유틸리티 타입
  • 유니언 타입 | 으로 여러 개의 속성을 선택하여 추가 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      interface User {
        name: string;
        age?: number;
        gender: string;
      }
        
      const nameObj: Pick<User, "name"> = {
        name: "jaegeon",
      };
    

Omit< T, K >

  • 객체로 주어진 타입 T의 모든 속성에서
    선택한 속성 K만 제외하여 만드는 유틸리티 타입
  • 유니언 타입 | 으로 여러 개의 속성을 선택하여 제거 가능

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      interface User {
        name: string;
        age?: number;
        gender: string;
      }
        
      const nameObj: Omit<User, "age" | "gender"> = {
        name: "jaegeon",
      };
    

Record< K, T >

  • 주어진 키 K와 주어진 타입 T을 가지는 객체를 만드는 유틸리티 타입
  • Record<string, never>빈 객체 생성 가능.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
      let objEmpty: Record<string, never> = {}; // 빈 객체 생성
      const score: { math: number; english: number; science: number } = {
        math: 90,
        english: 75,
        science: 100,
      };
      const score2: Record<string, number> = {
        math: 90,
        english: 75,
        science: 100,
      };
        
    

Exclude< T, K >

  • 유니언 타입으로 주어진 타입 T의 모든 속성에서
    선택한 속성 K만 제외하여 만드는 유틸리티
  • 유니언 타입 | 으로 여러 개의 속성을 선택하여 제거 가능

    1
    2
    
      type Mytype = "a" | "b" | "c";
      const res: Exclude<Mytype, "a" | "c"> = "b";
    

NonNullable< T >

  • 주어진 타입 T의 모든 속성에서
    nullundefined제외하여 만드는 유틸리티 타입
  • 유니언 타입 | 으로 여러 개의 속성을 선택하여 제거 가능

    1
    2
    
      type Mytype = string | number | boolean | null | undefined;
      type NonType = NonNullable<Mytype>;
    

ReturnType< T >

  • 함수로 주어진 타입 T반환 타입을 추출하여 만드는 유틸리티 타입
  • typeof 키워드를 사용하여, 주어진 함수의 전체 타입을 가져온다.

    1
    2
    3
    4
    5
    
      type Age = ReturnType<typeof getAge>; // number
      type AgeFunc = typeof getAge; // () => number
      function getAge() {
        return 20;
      }
    

typeof 키워드 - 함수

함수를 typeof으로 가져오면, 함수 전체의 타입을 가져온다.

1
2
3
4
type AgeFunc = typeof getAge; // () => number
function getAge() {
  return 20;
}



조건부 타입

T extends U ? X : Y (조건부 타입)

  • extends 후위의 U와 비교하여, 참과 거짓에 따라 → X, Y의 타입이 된다.
  • 예시

    1
    2
    3
    4
    5
    6
    
      type IsString<T> = T extends string ? "YES" : "NO";
      type A = IsString<string>; // "YES"
      type B = IsString<number>; // "NO"
        
      const a: A = "YES";
      const b: B = "NO";
    

    → 조건부 타입제네릭에 들어오는 타입을 제한하는 제약 조건과는 다른 것임!


조건부 타입 + infer

  • 제네릭이 아닌, 비교문에서의 타입을 추출하고 싶을 때 사용
  • 예시: 적용 전

    1
    2
    3
    4
    
      type ElementType<T> = T extends any[] ? any : T;
      type A = ElementType<10>; // 10
      type B = ElementType<[10, 20, 30]>; // any
      type C = ElementType<["10", "20", "30"]>; // any
    
  • 예시: 적용 후

    1
    2
    3
    4
    
      type ElementType<T> = T extends (infer U)[] ? U : T;
      type A = ElementType<10>; // 10
      type B = ElementType<[10, 20, 30]>; // 10 | 20 | 30
      type C = ElementType<["10", "20", "30"]>; // "10" | "20" | "30"
    

This post is licensed under CC BY 4.0 by the author.