유틸리티 타입 — Partial·Pick·Omit·Record
TS 가 제공하는 내장 도구 10종. 중급 파트의 시작.
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
이전: 10편 tsconfig · 현재: 11편 (중급 시작) · 다음 → 12편 조건부 타입 · 진행: 11/20