logoRawon_Log
홈블로그소개

Built with Next.js, Bun, Tailwind CSS and Shadcn/UI

Typescript

Typescript Utility Type

Rawon
2025년 11월 30일
목차
🎯 유틸리티 타입
🗺️ 맵드 타입 기반의 유틸리티 타입
❓ 조건부 타입 기반 유틸리티 타입
📝 맵드 타입 기반 유틸리티 타입
Partial<T>
Required<T>
Readonly<T>
Pick<T, K>
Omit<T, K>
Record<K, T> ⭐️
❓ 조건부 타입 기반 유틸리티 타입
Exclude<T, U>
Extract<T, U>
ReturnType<T>

목차

🎯 유틸리티 타입
🗺️ 맵드 타입 기반의 유틸리티 타입
❓ 조건부 타입 기반 유틸리티 타입
📝 맵드 타입 기반 유틸리티 타입
Partial<T>
Required<T>
Readonly<T>
Pick<T, K>
Omit<T, K>
Record<K, T> ⭐️
❓ 조건부 타입 기반 유틸리티 타입
Exclude<T, U>
Extract<T, U>
ReturnType<T>

이 글은 아래 강의를 바탕으로 정리한 글입니다. 🤗

plain
https://inf.run/UGoRu

🎯 유틸리티 타입

유틸리티 타입이란 제네릭, 맵드 타입, 조건부 타입 등의 타입 조작 기능을 이용해 실무에서 자주 사용되는 타입을 미리 만들어두고 TS가 자체적으로 제공해주는 특수한 타입들입니다.

📚 공식문서를 찾아보면 매우 많은 유틸리티 타입들이 있는데, 이중에서 자주 사용되는 핵심 유틸리티 타입은 약 9개입니다.

🗺️ 맵드 타입 기반의 유틸리티 타입

  1. Partial<T> : 특정 객체 타입의 모든 프로퍼티를 선택적으로 만들어주는 유틸리티 타입
  2. Required<T> : 특정 객체 타입의 모든 프로퍼티를 필수적으로 만들어주는 유틸리티 타입
  3. Readonly<T> : 특정 객체 타입의 모든 프로퍼티를 readonly 프로퍼티로 만들어주는 유틸리티 타입
  4. Pick<T, K> : 특정 객체 타입에서 특정 프로퍼티만 선택하여 새로운 객체 타입을 만들어주는 유틸리티 타입
  5. Omit<T, K> : 특정 객체 타입에서 특정 프로퍼티만 제외하여 새로운 객체 타입을 만들어주는 유틸리티 타입
  6. ⭐️ Record<K, T> : K는 객체 프로퍼티 키를 유니온으로 받고 T는 키들의 value 타입을 받아 새로운 객체 타입을 만들어주는 유틸리티 타입

❓ 조건부 타입 기반 유틸리티 타입

  1. Exclude<T, U> : T에서 U를 제거한 타입을 만들어주는 유틸리티 타입
  2. Extract<T, U> : T에서 U를 추출하여 새로운 타입을 만들어주는 유틸리티 타입
  3. ReturnType<T> : 함수의 반환값 타입을 추출하는 유틸리티 타입

📝 맵드 타입 기반 유틸리티 타입

Partial<T>

**Partial<T>**는 특정 객체 타입의 모든 프로퍼티를 선택적 프로퍼티로 변환합니다.

typescript
// Partial<T> 예시
interface Post {
  title: string;
  tags: string[];
  content: string;
  thumbnailUrl?: string;
}

// Partial<Post> 타입은 Post 타입의 모든 프로퍼티를 선택적으로 만들어주는 타입
const draft: Partial<Post> = {
  title: "제목",
  content: "내용",
};

💡 임시 저장(Draft) 기능처럼 일부 프로퍼티만 입력받아야 하는 경우에 유용합니다.

Required<T>

**Required<T>**는 특정 객체 타입의 모든 프로퍼티를 필수 프로퍼티로 변환합니다.

typescript
// Required<T> 예시
const withThumbnailPost: Required<Post> = {
  title: "제목",
  tags: ["1", "2", "3"],
  content: "내용",
  thumbnailUrl: "
https://example.com/thumbnail.jpg
",
};

⚠️ 선택적 프로퍼티가 포함된 타입을 모두 필수로 만들어야 할 때 사용합니다. 위 예시에서 thumbnailUrl은 원래 선택적 프로퍼티지만, Required를 사용하면 반드시 제공해야 합니다.

Readonly<T>

**Readonly<T>**는 특정 객체 타입의 모든 프로퍼티를 읽기 전용 프로퍼티로 변환합니다.

typescript
// Readonly<T> 예시
const readonlyPost: Readonly<Post> = {
  title: "제목",
  tags: ["1", "2", "3"],
  content: "내용",
  thumbnailUrl: "
https://example.com/thumbnail.jpg
",
};

// readonlyPost.title = "제목2";
// ❌ 오류 발생, readonly 프로퍼티는 수정 불가

🚨 객체를 생성한 후 수정되어서는 안 되는 불변 데이터를 다룰 때 유용합니다.

Pick<T, K>

**Pick<T, K>**는 특정 객체 타입에서 원하는 프로퍼티만 선택하여 새로운 객체 타입을 만듭니다.

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

// Pick<T, K> 예시
// Post 타입에서 title과 content 프로퍼티만 선택하여 새로운 객체 타입을 만듦.
const legacyPost: Pick<Post, "title" | "content"> = {
  title: "옛날 제목",
  content: "옛날 내용",
};

💡 큰 객체 타입에서 필요한 일부 프로퍼티만 사용하고 싶을 때 유용합니다.

Omit<T, K>

**Omit<T, K>**는 특정 객체 타입에서 특정 프로퍼티만 제외하여 새로운 객체 타입을 만듭니다.

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

// Omit<T, K> 예시
// Post 타입에서 title 프로퍼티를 제외하여 새로운 객체 타입을 만듦.
const NoTitlePost: Omit<Post, "title"> = {
  //   title: "최신 제목", // ❌ 오류 발생, title 프로퍼티가 제외되었기 때문
  tags: ["1", "2", "3"],
  content: "최신 내용",
  thumbnailUrl: "
https://example.com/thumbnail.jpg
",
};

💡 Pick과 반대 개념으로, 제외하고 싶은 프로퍼티가 적을 때 Omit이 더 편리합니다.

Record<K, T> ⭐️

**Record<K, T>**는 객체의 키와 값 타입을 동시에 정의하여 새로운 객체 타입을 만듭니다.

예를 들어 화면 크기에 따라 3가지 버전의 썸네일을 지원한다고 가정했을 때, 화면 크기 별 url 타입을 별도로 정의하는데, 만약 여기에 watch 버전이 추가되어야 한다면 똑같이 생긴 프로퍼티를 하나 더 추가해주어야 하는 중복 코드가 발생하게 되는데 이럴 때, 다음과 같이 Record 타입을 이용하면 됩니다.

K에는 어떤 프로퍼티들이 있을지 String Literal Union 타입을 할당하고 T에는 프로퍼티의 값을 할당합니다.

typescript
// 레거시
type ThumbnailLegacy = {
  large: { url: string };
  medium: { url: string };
  small: { url: string };
};

// Record<K, T> 예시
type Thumbnail = Record<"large" | "medium" | "small", { url: string }>;

// 만약 watch 키를 추가해야 한다면
type Thumbnail2 = Record<
  "large" | "medium" | "small" | "watch",
  { url: string }
>;

⭐ 동일한 구조의 프로퍼티가 여러 개 필요할 때 중복 코드를 줄일 수 있는 강력한 유틸리티 타입입니다.


❓ 조건부 타입 기반 유틸리티 타입

Exclude<T, U>

**Exclude<T, U>**는 T로부터 U를 제거하는 타입입니다.

typescript
// Exclude<T, U> 예시
// string | boolean 타입에서 boolean 타입을 제거한 타입을 만듦.
type A = Exclude<string | boolean, boolean>; // string 타입

💡 Union 타입에서 특정 타입만 제외하고 싶을 때 사용합니다.

Extract<T, U>

**Extract<T, U>**는 T로부터 U를 추출하는 타입입니다.

typescript
// Extract<T, U> 예시
// string | boolean 타입에서 boolean 타입을 추출한 타입을 만듦.
type B = Extract<string | boolean, boolean>; // boolean 타입

💡 Exclude와 반대 개념으로, Union 타입에서 특정 타입만 추출하고 싶을 때 사용합니다.

ReturnType<T>

**ReturnType<T>**는 타입변수 T에 할당된 함수 타입의 반환값 타입을 추출하는 타입입니다.

typescript
// ReturnType<T> 예시
function funcA() {
  return "hello";
}

function funcB() {
  return 10;
}

type C = ReturnType<typeof funcA>; // string 타입
type D = ReturnType<typeof funcB>; // number 타입

💡 함수의 반환 타입을 별도로 정의하지 않고도 추출할 수 있어, 함수와 타입 간의 일관성을 유지하기 쉽습니다.