이들은 TypeScript의 타입 레벨 프로그래밍 도구입니다. 기존 타입으로부터 새로운 타입을 계산합니다.
Mapped type — 각 프로퍼티를 변환
Mapped type은 타입의 키를 순회하며 각각을 변환합니다:
ts
<T> = { [K keyof T]: T[K] };
<T> = { [K keyof T]?: T[K] };
{ : ; : ; }
= <>;
이들은 TypeScript의 타입 레벨 프로그래밍 도구입니다. 기존 타입으로부터 새로운 타입을 계산합니다.
Mapped type은 타입의 키를 순회하며 각각을 변환합니다:
<T> = { [K keyof T]: T[K] };
<T> = { [K keyof T]?: T[K] };
{ : ; : ; }
= <>;
[K in keyof T]는 각 키 K를 순회하며, T[K]는 그 키의 값 타입입니다. Partial, Readonly, Required가 이렇게 구현됩니다. 키를 재매핑하거나 modifier를 추가/제거할 수도 있습니다(-readonly, -?로 제거).
type IsString<T> = T extends string ? "yes" : "no";
type A = IsString<string>; // "yes"
type B = IsString<number>; // "no"
T extends U ? X : Y는 타입 레벨의 if/else입니다. infer를 사용하면 조건 안에서 타입을 추출할 수 있습니다:
type ElementOf<T> = T extends (infer U)[] ? U : never;
type E = ElementOf<string[]>; // string
// 함수 값을 가진 프로퍼티만 optional로 만들기
type PartialMethods<T> = {
[K in keyof T]: T[K] extends Function ? T[K] | undefined : T[K];
};
Mapped type은 conditional 안에서 union에 대해 **분배(distribute)**되기도 하여 강력한 변환을 가능하게 합니다.
Mapped type과 conditional type은 라이브러리가 정밀한 타입 관계를 표현하게 해줍니다. 유틸리티 타입을 구현하고, 폼/검증 라이브러리, ORM 쿼리 빌더, 응답 shape를 추론하는 API 클라이언트를 떠받칩니다.
고급 주제이지만 이를 이해하면 TypeScript 타입 시스템이 어떻게 그토록 표현력이 풍부할 수 있는지 설명되며, 변형들을 손으로 작성하는 대신 재사용 가능한 타입 변환을 만들 수 있게 됩니다.