
1편에서는 Omit, Pick, Partial, Readonly를 다뤘습니다.
2편에서는 조금 더 다양한 상황에서 쓰이는 유틸리티 타입을 소개합니다.
| 유틸리티 타입 | 설명 |
|---|---|
Required<T> | T의 모든 키를 필수로 만든 타입 |
Record<K, V> | K를 키, V를 값으로 하는 타입 |
Extract<T, U> | T에서 U에 해당하는 타입만 추출 |
Exclude<T, U> | T에서 U에 해당하는 타입을 제거 |
ReturnType<T> | 함수 T의 반환 타입을 추출 |
Awaited<T> | Promise를 재귀적으로 벗겨낸 타입을 추출 |
모든 유틸리티 타입을 보고 싶다면 유틸리티 타입을 참고해주세요.
게시판 API 만들기
아래 Post 타입 하나로 4가지 상황에 맞는 타입을 유틸리티 타입만 써서 만들어보세요.
type Post = {
id: number;
title: string;
content: string;
thumbnail?: string;
status: "draft" | "published" | "deleted";
authorId: number;
createdAt: Date;
updatedAt: Date;
};
관리자가 게시글을 수정할 때는 모든 필드(thumbnail 포함)를 반드시 제출해야 합니다.
Post에서 수정 가능한 필드(title, content, thumbnail, status)만 골라, 모든 필드가 필수인 수정 요청 타입을 정의하십시오.
문제 풀어보기 =>
type UpdatePostDTO = ?
관리자 대시보드에서 게시글 상태(draft, published, deleted)별 게시글 수를 표시합니다.
상태값을 키로, 게시글 수(number)를 값으로 하는 타입을 정의하십시오.
문제 풀어보기 =>
type PostStatusCount = ?
status가 "draft" | "published" | "deleted" 중에서
외부에 노출해도 되는 "published" 상태 타입만 추출하십시오.
문제 풀어보기 =>
type PublishedStatus = ?
아래 함수의 반환 타입을 함수 시그니처를 직접 복사하지 않고 추출하십시오.
문제 풀어보기 =>
async function getPostList(): Promise<Post[]> {
return fetch('/api/posts').then(res => res.json());
}
type PostListResponse = ?
type UpdatePostDTO = Required<Pick<Post, "title" | "content" | "thumbnail" | "status">>;
// 결과
type UpdatePostDTO = {
title: string;
content: string;
thumbnail: string; // optional → required
status: "draft" | "published" | "deleted";
}
type PostStatusCount = Record<Post["status"], number>;
// 결과
type PostStatusCount = {
draft: number;
published: number;
deleted: number;
}
type PublishedStatus = Extract<Post["status"], "published">;
// 결과
type PublishedStatus = "published"
// 응용: 여러 개 추출도 가능
type VisibleStatus = Extract<Post["status"], "published" | "draft">;
// "published" | "draft"
type PostListResponse = Awaited<ReturnType<typeof getPostList>>;
// 결과
type PostListResponse = Post[]
// ReturnType → Promise<Post[]>
// Awaited → Promise를 벗겨서 Post[]
Required — 선택적 필드를 전부 필수로 만들 때Record — 키-값 쌍의 객체 타입을 깔끔하게 정의할 때Extract — 유니온에서 원하는 타입만 골라낼 때Exclude — 유니온에서 원하는 타입만 제거할 때ReturnType — 함수 반환 타입을 직접 복사하지 않고 추출할 때Awaited — Promise를 벗겨 실제 값 타입을 꺼낼 때타입을 하드코딩하지 말고, 이미 정의된 타입에서 파생시키세요.
함수 시그니처가 바뀌어도 ReturnType을 쓰면 연결된 타입이 자동으로 따라옵니다.