SHIN
TypeScript 실전 팁 10선
10편유틸리티 타입을 잘 활용하면 중복 타입 선언 없이 기존 타입에서 파생 타입을 만들 수 있습니다.
interface User {
id: number
name: string
email: string
password: string
createdAt: Date
role: 'admin' | 'user'
}// 업데이트 시 일부 필드만 전달
function updateUser(id: number, data: Partial<User>) {
// data.name, data.email 등 원하는 필드만 전달 가능
}
updateUser(1, { name: '홍길동' }) // ✅
updateUser(1, { name: '홍', email: 'a@b' }) // ✅interface Config {
host?: string
port?: number
timeout?: number
}
// 모든 설정값이 채워진 완성 상태
type ResolvedConfig = Required<Config>
// { host: string; port: number; timeout: number }// 공개 API 응답용 — 비밀번호 제외
type PublicUser = Pick<User, 'id' | 'name' | 'email'>
// 로그인 폼용
type LoginForm = Pick<User, 'email' | 'password'>// 생성 요청 — id와 createdAt은 서버에서 자동 생성
type CreateUserDto = Omit<User, 'id' | 'createdAt'>
// Pick보다 Omit이 더 편할 때: 제거할 필드가 선택할 필드보다 적을 때// 역할별 권한 정의
type Permissions = Record<User['role'], string[]>
const permissions: Permissions = {
admin: ['read', 'write', 'delete'],
user: ['read'],
}
// 키 타입을 유니온으로 제한
type StatusMap = Record<'pending' | 'active' | 'inactive', boolean>async function fetchUser(id: number) {
return { id, name: '홍길동', email: 'hong@example.com' }
}
type UserResult = Awaited<ReturnType<typeof fetchUser>>
// { id: number; name: string; email: string }
// 라이브러리 함수의 반환 타입을 재사용할 때 특히 유용function createPost(title: string, content: string, tags: string[]) {}
type PostParams = Parameters<typeof createPost>
// [title: string, content: string, tags: string[]]
// 첫 번째 파라미터만 추출
type TitleParam = Parameters<typeof createPost>[0] // stringconst config: Readonly<Config> = {
host: 'localhost',
port: 3000,
timeout: 5000,
}
config.port = 8080 // ❌ 컴파일 오류: 읽기 전용 속성// 업데이트 DTO: id 제외, 나머지는 선택적
type UpdateUserDto = Partial<Omit<User, 'id' | 'createdAt'>>
// API 응답: 비밀번호 제외, 모두 읽기 전용
type UserResponse = Readonly<Omit<User, 'password'>>유틸리티 타입을 조합하면 단 한 줄로 복잡한 파생 타입을 표현할 수 있습니다.