타입스크립트 교재 · 11편 / 20편

유틸리티 타입 — Partial·Pick·Omit·Record

TS 가 제공하는 내장 도구 10종. 중급 파트의 시작.

중급읽는 시간 7분2026-05-17
Partial/Pick/Omit/Record 등 유틸리티 타입이 기존 타입을 변형하는 도식

TS 가 기본 제공하는 유틸리티 타입은 기존 타입에서 새 타입을 즉시 만들어 줍니다. Partial<User> 한 줄로 "User 의 모든 속성을 옵션으로" 가 됩니다. 11편은 매일 만나는 10개를 정리합니다 — 중급 파트의 시작.

기준 타입

interface User {
  id: number;
  name: string;
  email: string;
  age?: number;
}

Partial<T> — 모두 옵션으로

type UserPatch = Partial<User>;
// = { id?: number; name?: string; email?: string; age?: number }

function updateUser(id: number, patch: Partial<User>) {
  // 일부만 보내도 OK
}
updateUser(1, { name: "준석" });

Required<T> — 모두 필수로

type StrictUser = Required<User>;
// age 의 ? 제거됨 — { id; name; email; age }

Readonly<T> — 변경 금지

const u: Readonly<User> = { id: 1, name: "준성", email: "[email protected]" };
u.name = "준석";   // ❌ Cannot assign to 'name' (read-only)

Pick<T, K> — 일부 키만 골라서

type PublicUser = Pick<User, "id" | "name">;
// = { id: number; name: string }

Omit<T, K> — 일부 키만 빼고

type UserCreateInput = Omit<User, "id">;
// = { name; email; age? }  ← 서버에서 id 만들어줄 때

Pick vs Omit. 둘은 거울. 보통 "가져올 게 많으면 Omit, 적으면 Pick" 이 가독성 좋습니다. 키가 3개인데 5개 omit 하느니, 3개 pick 이 명확.

Record<K, V> — 키-값 형태의 타입

type Role = "admin" | "user" | "guest";

type PermsByRole = Record<Role, boolean>;
// = { admin: boolean; user: boolean; guest: boolean }

const perms: PermsByRole = {
  admin: true,
  user: true,
  guest: false,
};

// 사전형 객체
type Cache = Record<string, { value: number; ttl: number }>;

Exclude<T, U> · Extract<T, U> — 유니온 좁히기

type Status = "pending" | "paid" | "shipped" | "cancelled";

type Active = Exclude<Status, "cancelled">;
// = "pending" | "paid" | "shipped"

type Terminal = Extract<Status, "shipped" | "cancelled" | "x">;
// = "shipped" | "cancelled"  ← T 안에 있는 것만 골라냄

NonNullable<T> — null·undefined 제거

type MaybeUser = User | null | undefined;
type DefinitelyUser = NonNullable<MaybeUser>;   // User

ReturnType<F> · Parameters<F> — 함수 시그니처에서

function createUser(name: string, age: number) {
  return { id: 1, name, age, createdAt: new Date() };
}

type CreatedUser = ReturnType<typeof createUser>;
// = { id: number; name: string; age: number; createdAt: Date }

type CreateArgs = Parameters<typeof createUser>;
// = [name: string, age: number]

typeof + ReturnType 의 위력. 라이브러리 함수의 반환을 직접 적기 귀찮을 때 가장 자주 씁니다. 함수 본문이 바뀌어도 타입이 자동으로 따라옴.

Awaited<T> — Promise 풀기

async function loadUser() {
  return { id: 1, name: "준성" };
}
//        ^ Promise<{ id; name }>

type User2 = Awaited<ReturnType<typeof loadUser>>;
// = { id: number; name: string }   ← Promise 벗김

실전 패턴 — 같이 자주 쓰는 조합

// "id 빼고 나머지 다 옵션" — PATCH 요청용
type UpdateUserInput = Partial<Omit<User, "id">>;

// "User 의 일부 필드만 readonly"
type WithReadonlyId<T extends { id: unknown }> =
  Readonly<Pick<T, "id">> & Omit<T, "id">;

// "API 응답 타입에서 success 만"
type SuccessResponse = Extract<ApiResponse, { ok: true }>;

한 표로 정리

유틸리티한 줄 설명
Partial<T>모든 속성 옵션
Required<T>모든 속성 필수
Readonly<T>모든 속성 readonly
Pick<T, K>K 키만 골라
Omit<T, K>K 키만 빼고
Record<K, V>키-값 객체 타입
Exclude<T, U>T 에서 U 제외
Extract<T, U>T 에서 U 와 겹치는 것만
NonNullable<T>null/undefined 제거
ReturnType<F>함수 반환 타입
Parameters<F>함수 매개변수 튜플
Awaited<T>Promise 벗기기

12편 — 조건부 타입

T extends U ? X : Y — 분기하는 타입과 infer 키워드.

📚 쉽게 배우는 타입스크립트 교재
이전: 10편 tsconfig · 현재: 11편 (중급 시작) · 다음 → 12편 조건부 타입 · 진행: 11/20

© 2026 주나이테크(주) @JUNAITECH