개요
TypeScript의 고급 타입은 단순 오류 방지 수준을 넘어 재사용성과 유지보수성을 끌어올리는 핵심 도구임 제네릭, 유니온·인터섹션, 매핑 타입, 조건부 타입, 그리고 실무에서 자주 쓰는 유틸리티 타입을 간단 예시와 함께 정리함
제네릭
타입을 값처럼 받아서 사용하는 패턴으로, 선언 시점이 아니라 사용 시점에 타입을 결정함 any 대비 타입 정보를 잃지 않으면서 다양한 타입을 수용 가능
- 기본 형태 사용
- 입력과 출력 타입의 관계를 보존하는 데 초점
function wrap(value: any) {
return { value }
}
function wrapBox<T>(value: T) {
return { value }
}
const stringBox = wrapBox("Hello")
const numberBox = wrapBox(123)- T는 관습적 이름이며 의미가 드러나는 이름 사용 권장
- 제네릭 제한이 필요한 경우 extends를 사용해 제약 가능 ex)
유니온과 인터섹션
여러 타입을 조합해 표현력을 높이는 방법
유니온 타입 |
A 또는 B 의미의 합집합 타입 타입 가드로 분기 처리 필요
type ID = string | number
function printId(id: ID) {
if (typeof id === 'string') {
console.log(id.toUpperCase())
} else {
console.log(id)
}
}인터섹션 타입 &
A 그리고 B 의미의 교집합 타입 여러 속성을 모두 갖는 구조 합성에 유용
type Person = { name: string }
type Employee = { employeeId: number }
type Staff = Person & Employee
const newStaff: Staff = { name: "Kim", employeeId: 1234 }매핑 타입
기존 타입의 키를 순회하며 새로운 형태로 변환하는 기법 반복 선언을 줄이는 데 효과적
- 기본 형태 [K in keyof T]
type User = { name: string; age: number }
type PartialUser = {
[K in keyof User]?: User[K]
}
const userUpdate: PartialUser = { age: 30 }조건부 타입
타입 차원에서 if-else 분기를 수행
- 문법 예시
T extends U ? X : Y
type MyExclude<T, U> = T extends U ? never : T
type Result = MyExclude<'a' | 'b' | 'c', 'a'>유틸리티 타입
매핑·조건부 타입으로 구성된 표준 유틸리티 모음 주요 타입과 용도 중심으로 기억해두면 실무 편의성 상승
- Partial 모든 속성을 선택적으로 변경 업데이트 페이로드 정의에 적합
- Pick<T, K> T에서 K에 해당하는 속성만 선택 필요한 최소 필드만 추출
- Omit<T, K> T에서 K에 해당하는 속성만 제외 민감 정보 제거 등 필드 차단에 활용
- Record<K, T> 키가 K이고 값이 T인 객체 맵 구조 정의에 적합
- Readonly 모든 속성을 읽기 전용으로 변경 불변성 유지가 필요한 데이터에 적용
요약과 활용 팁
- 제네릭은 타입을 인자로 받는 함수라는 관점으로 이해하면 설계가 단순해짐
- 유니온은 범위를 넓히고 인터섹션은 구체성을 강화함 목적에 맞게 선택
- 반복 구조가 보이면 매핑 타입 또는 유틸리티 타입부터 검토
- 분기 처리가 필요한 순간에는 조건부 타입으로 타입 레벨 로직을 모델링
마무리
타입은 문서와 테스트의 역할을 함께 수행함 초기 설계에서 관계와 제약을 타입으로 명시하면 런타임 버그를 조기 차단 가능 팀 단위로 공용 타입 유틸을 축적하면 API 변경과 리팩터링 비용을 꾸준히 줄일 수 있음
참고자료
- https://www.typescriptlang.org/docs/handbook/2/generics.html
- https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types
- https://www.typescriptlang.org/docs/handbook/2/objects.html#intersection-types
- https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
- https://www.typescriptlang.org/docs/handbook/2/conditional-types.html
- https://www.typescriptlang.org/docs/handbook/utility-types.html