TypeScript제네릭과 타입 조작

mapped types와 key remapping

기존 타입의 키를 순회하며 새 타입을 만드는 mapped types와 `as`를 이용한 key remapping을 정리합니다.

마지막 수정 2026년 3월 22일

기본 패턴

ts
type Flags<T> = {
  [K in keyof T]: boolean;
};

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

설명

  • mapped type은 기존 타입의 키를 한 번 순회하면서 새로운 타입을 만드는 문법입니다. 즉 "같은 키 집합을 다른 규칙으로 바꾸고 싶다"는 문제를 푸는 도구입니다.
  • Partial<T>, Readonly<T>, Record<K, V> 같은 유틸리티 타입도 결국 이런 아이디어 위에 서 있습니다. 그래서 mapped type을 이해하면 내장 유틸리티 타입도 더 잘 읽히게 됩니다.
  • 가장 기본적인 사용은 "모든 속성을 boolean으로 바꾸기", "모든 속성을 optional로 만들기", "readonly를 제거하기"처럼 키는 유지하고 속성 성질만 바꾸는 경우입니다.
  • as를 이용한 key remapping은 한 단계 더 나아가 키 이름 자체를 바꾸게 해 줍니다. 이때 template literal types와 결합하면 getName, setAge, onStatusChanged 같은 새 이름을 타입 수준에서 만들 수 있습니다.
  • 실무에서는 API DTO 변환, 폼 상태 타입 생성, selector/getter 타입 만들기, 서버/클라이언트 모델 변형에서 mapped type이 특히 빛납니다.

빠른 정리

문법의미
[K in keyof T]T의 모든 키를 순회
T[K]현재 키가 가리키는 값 타입
readonly / ? modifier속성 성질을 바꿈
as ...키 이름 자체를 다시 만듦
잘 맞는 상황반복적인 객체 타입 변형, getter/setter 생성

주의할 점

mapped type은 강력하지만 한 번에 너무 많은 규칙을 넣으면 타입이 급격히 읽기 어려워집니다. 자주 쓰는 변형은 별도 이름을 붙여두는 편이 유지보수에 훨씬 유리합니다.

참고 링크

2 sources