[TS] 유틸리티 타입 정리

정은·2025년 6월 16일

목차

  1. 유틸리티 타입이란
  2. Partial<T>
  3. Required<T>
  4. Readonly<T>
  5. Pick<T, K>
  6. Omit<T, K>
  7. Record<K, V>
  8. Exclude<T, K>
  9. Extract<T, K>
  10. ReturnType<T>

유틸리티 타입 ?

타입스크립트가 자체적으로 제공하는 특수한 타입

맵드 타입 기반: 목차 1~6번
(key를 기준으로 새로운 타입을 만든다. 키의 반복을 통해 속성 자체를 바꾸는 것에 초점)

조건부 타입 기반: 목차 7~9번
(타입이 어떤 조건에 따라 바뀌는 "삼항 연산자 스타일" 분기)

Partial<T>

특정 객체 타입의 모든 프로퍼티를 선택적 프로퍼티로 변환
👉 기존 객체 타입에 정의된 프로퍼티 중 일부분만 사용할 수 있도록 도와주는 타입

interface Post {
  title: string;
  tags: string[];
  content: string;
  thumbnailURL?: string;
}

const draft: Partial<Post> = {
  title: "제목",
  content: "내용",
};

Required<T>

특정 객체 타입의 모든 프로퍼티를 필수 프로퍼티로 변환 (partial 반대)
👉 사용 시 옵셔널 프로퍼티 생략 불가능 (생략 시 오류 발생)

interface Post {
  title: string;
  tags: string[];
  content: string;
  thumbnailURL?: string;
}

const withThumbnailPost: Required<Post> = {
  title: "제목",
  tags: ["ts"],
  content: "",
  // thumbnailURL: "",
};

Readonly<T>

특정 객체 타입의 모든 프로퍼티를 읽기 전용 프로퍼티로 변환
👉 사용 시 수정 불가능 (수정 시 오류 발생)

interface Post {
  title: string;
  tags: string[];
  content: string;
  thumbnailURL?: string;
}

const readonlyPost: Readonly<Post> = {
  title: "수정 불가",
  tags: [],
  content: "",
};

readonlyPost.content = '수정 시도';

Pick<T, K>

특정 객체 타입으로부터 특정 프로퍼티만 골라내는 타입

interface Post {
  title: string;
  tags: string[];
  content: string;
  thumbnailURL?: string;
}

const legacyPost: Pick<Post, "title" | "content"> = {
  title: "",
  content: "",
};
// 추출된 타입 : { title : string; content : string }

Omit<T, K>

특정 객체 타입으로부터 특정 프로퍼티만을 제거하는 타입

interface Post {
  title: string;
  tags: string[];
  content: string;
  thumbnailURL?: string;
}

const noTitlePost: Omit<Post, "title"> = {
  content: "",
  tags: [],
  thumbnailURL: "",
};

Record<K, V>

type 중복 프로퍼티 추가 시 이용하는 타입
👉 K에는 어떤 프로퍼티들이 있을지 String Literal Union 타입을 할당, V에는 프로퍼티의 값 타입을 할당

type Thumbnail = {
  large: {
    url: string;
  };
  medium: {
    url: string;
  };
  small: {
    url: string;
  };
};

// 위 코드를 아래처럼 사용 가능

type Thumbnail = Record<
  "large" | "medium" | "small",
  { url: string }
>;

아래는 조건부 타입 기반 타입 정리 !

Exclude<T, K>

Exclude 타입은 T로부터 U를 제거하는 타입
👉 여러 개가 합쳐진 유니언 타입에서 특정 케이스만 제거하고 싶을 때 사용

type Status = "loading" | "success" | "error" | "idle";

// Status 타입에서 "loading" 상태만 제외하고 싶어요.
type NonLoadingStatus = Exclude<Status, "loading">;
// 결과 타입 NonLoadingStatus는 "success" | "error" | "idle" 가 돼요!

let currentStatus: NonLoadingStatus = "success";
// currentStatus = "loading"; // 에러! NonLoadingStatus 타입에는 "loading"이 없어요.

Extract<T, K>

Extract 타입은 T로 부터 U를 추출하는 타입입니다
👉 유니언 타입 중에서 특정 타입들만 따로 뽑아내고 싶을 때 사용

type EventType = "click" | "mouseover" | "keydown" | "keyup";

// EventType 중에서 마우스 관련 이벤트("click", "mouseover")만 뽑아내고 싶어요.
type MouseEventType = Extract<EventType, "click" | "mouseover">;
// 결과 타입 MouseEventType는 "click" | "mouseover" 가 돼요!

let mouseEvent: MouseEventType = "click";
// mouseEvent = "keydown"; // 에러! MouseEventType 타입에는 "keydown"이 없어요.

ReturnType<T>

타입변수 T에 할당된 함수 타입의 반환값 타입을 추출하는 타입

type ReturnType<T extends (...args: any) => any> = T extends (
  ...agrs: any
) => infer R
  ? R
  : never;

function funcA() {
  return "hello";
}

function funcB() {
  return 10;
}

type ReturnA = ReturnType<typeof funcA>;
// string

type ReturnB = ReturnType<typeof funcB>;
// number

코드 예시 출처
한 입 크기로 잘라먹는 타입스크립트
https://velog.io/@outofearth/posts

0개의 댓글