매핑된 타입(Mapped Types)은 기존 타입의 키를 하나씩 돌며 새 타입을 만드는 문법([K in keyof T]: …)이다. keyof T는 객체 타입의 키 유니언을, T[K](인덱스 접근 타입, Indexed Access Type)는 그 키의 값 타입을 꺼낸다.
type User = { id: string; age: number }
type UserKeys = keyof User // 'id' | 'age'
type Age = User['age'] // number
type Nullable<T> = { [K in keyof T]: T[K] | null }
type ValueOf<T> = T[keyof T]수정자(Mapping Modifiers) 더하고 빼기
readonly와 ?를 붙이거나 -로 뗄 수 있다. 읽기 전용 타입을 폼 상태처럼 고칠 수 있는 사본으로 바꿀 때 쓴다.
type Mutable<T> = { -readonly [K in keyof T]: T[K] }
type Concrete<T> = { [K in keyof T]-?: T[K] }(obj as any).field = …로 우회하는 것보다 의도가 드러나고 나머지 검사는 유지된다.
상수 객체에서 유니언 뽑기
const routes = { home: '/', profile: '/profile' } as const
type RouteName = keyof typeof routes // 'home' | 'profile'
type RoutePath = (typeof routes)[RouteName] // '/' | '/profile'라우트·권한·이벤트 이름을 값과 타입 두 군데에 따로 선언하지 않아도 된다. enum 대신 이 패턴을 쓰는 이유는 enum과 as const 객체에 있다.
<K extends keyof T>제약과 함께 쓰면 테이블 컬럼 정의나 폼 필드 접근을 안전하게 만들 수 있다(제네릭)- 키 이름 자체를 바꾸려면 템플릿 리터럴 타입와
as절을 쓴다 - 내장 유틸리티 타입(
Partial,Readonly,Pick)가 모두 이 문법으로 구현돼 있다