C.W.K.
Stream
Lesson 04 of 06 · published

Mapped 타입: Key 에 Loop

~11 min · type-manipulation, mapped-types, type-transformation

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"Mapped 타입이 타입-레벨 loop. Key 에 iterate, 새 모양 만들어."

Mapped-type 문법

{ [K in keyof T]: NewType } 가 T 의 key 에 iterate 해서 새 object 타입 만들어. 각 key K 에 대해, property 의 value 타입이 colon 후에 너가 쓴 어떤 표현이든 — 보통 K, T[K], 또는 둘 다 포함.

이게 `Partial`, `Required`, `Readonly`, 많은 utility 타입 만드는 법. 하나 보자:

type Partial<T> = { [K in keyof T]?: T[K] };

T 의 key 에 loop, 각각에 `?` 로 optional 표시, 원래 value 타입 유지. Identity mapped 타입에서 3 변화, 어느 것도 복잡 안 함.

Modifier: `+` 와 `-`

Mapped 타입이 modifier 명시적으로 추가/제거 가능. +? 가 optional 추가, -? 가 optional 제거. +readonly 가 readonly 추가, -readonly 가 제거. Required-? 써서 optionality strip.

Plus 가 보통 생략 (default 방향). Minus 는 key 가 이미 가진 modifier 제거하고 싶을 때 쓰는 거.

`as` 통한 key remapping

TypeScript 4.1 이 mapped 타입에 as 추가: { [K in keyof T as NewKey]: ... }. `NewKey` 가 string-조작 타입 표현 (자주 template literal) 일 수, 통과하는 key 변환. 'get prefix 모든 key 에 추가' 같은 타입 빌드 가능.

Mapped 타입이 대부분 타입-레벨 변환의 기초. 하나 쓸 수 있게 되면 utility 타입 어느 거든 처음부터 빌드 가능 — 그리고 built-in 어느 것도 딱 안 맞을 때 자기 거 손 뻗는 자신 발견.

Code

Mapped 타입 — 모든 utility 가 이 패턴들로 빌드·typescript
// Identity — 문법 이해에 유용.
type Identity<T> = { [K in keyof T]: T[K] };

// Partial — 모든 key 에 `?` 추가.
type MyPartial<T> = { [K in keyof T]?: T[K] };

// Required — 모든 key 에서 `?` strip.
type MyRequired<T> = { [K in keyof T]-?: T[K] };

// Readonly — 모든 key 에 `readonly` 추가.
type MyReadonly<T> = { readonly [K in keyof T]: T[K] };

// 모든 property null-or-original 만들기.
type Nullable<T> = { [K in keyof T]: T[K] | null };

// `as` 통한 key remapping — 'get' prefix 추가.
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type UserGetters = Getters<{ name: string; age: number }>;
// { getName: () => string; getAge: () => number }

External links

Exercise

T 의 모든 property 를 string 타입으로 변환하는 Stringify<T> mapped 타입 써. Stringify<{ a: number; b: boolean }>{ a: string; b: string } 여야. 그다음 모든 값을 Promise<T[K]> 로 wrap 하는 Promiseify<T> 써. 둘 다 기대대로 행동 확인.
Hint
type Stringify<T> = { [K in keyof T]: string }. type Promiseify<T> = { [K in keyof T]: Promise<T[K]> }. 패턴 동일; colon 오른쪽만 바뀜.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.