Skip to content

Commit 152f893

Browse files
Merge pull request #132 from bumkeyy/mapped_types_bumkeyy
Co-authored-by: yeonjuan <[email protected]>
2 parents 0af42a1 + 93cf0c9 commit 152f893

File tree

1 file changed

+160
-0
lines changed

1 file changed

+160
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
title: Mapped Types
3+
layout: docs
4+
permalink: /ko/docs/handbook/2/mapped-types.html
5+
oneline: "이미 존재하는 타입을 재사용해서 타입을 생성하기"
6+
---
7+
8+
중복을 피하기 위해서 다른 타입을 바탕으로 새로운 타입을 생성할 수 있습니다.
9+
10+
매핑된 타입은 이전에 선언하지 않았던 프로퍼티의 타입을 선언할 수 있는 인덱스 시그니처 문법로 구성됩니다.
11+
12+
```ts twoslash
13+
type Horse = {};
14+
// ---cut---
15+
type OnlyBoolsAndHorses = {
16+
[key: string]: boolean | Horse;
17+
};
18+
19+
const conforms: OnlyBoolsAndHorses = {
20+
del: true,
21+
rodney: false,
22+
};
23+
```
24+
25+
매핑된 타입은 `PropertyKey`([`keyof`을 통해서](/docs/handbook/2/indexed-access-types.html) 자주 생성되는)의 조합을 사용하여 키를 통해 타입을 반복적으로 생성하는 제너릭 타입입니다.
26+
27+
```ts twoslash
28+
type OptionsFlags<Type> = {
29+
[Property in keyof Type]: boolean;
30+
};
31+
```
32+
33+
다음 예제에서, `OptionsFlags``Type` 타입의 모든 프로퍼티를 가져와서 해당 값을 불린으로 변경합니다.
34+
35+
```ts twoslash
36+
type OptionsFlags<Type> = {
37+
[Property in keyof Type]: boolean;
38+
};
39+
// ---cut---
40+
type FeatureFlags = {
41+
darkMode: () => void;
42+
newUserProfile: () => void;
43+
};
44+
45+
type FeatureOptions = OptionsFlags<FeatureFlags>;
46+
// ^?
47+
```
48+
49+
### Mapping Modifiers
50+
51+
매핑중에는 추가할 수 있는 수정자로 `readonly``?` 있습니다. 각각 가변성과 선택성에 영향을 미칩니다.
52+
53+
`-` 또는 `+`를 접두사로 붙여서 이런 수정자를 추가하거나 제거할 수 있습니다. 접두사를 추가하지 않으면 `+`로 간주합니다.
54+
55+
```ts twoslash
56+
// 타입의 프로퍼티에서 'readonly' 속성을 제거합니다
57+
type CreateMutable<Type> = {
58+
-readonly [Property in keyof Type]: Type[Property];
59+
};
60+
61+
type LockedAccount = {
62+
readonly id: string;
63+
readonly name: string;
64+
};
65+
66+
type UnlockedAccount = CreateMutable<LockedAccount>;
67+
// ^?
68+
```
69+
70+
```ts twoslash
71+
// 타입의 프로퍼티에서 'optional' 속성을 제거합니다
72+
type Concrete<Type> = {
73+
[Property in keyof Type]-?: Type[Property];
74+
};
75+
76+
type MaybeUser = {
77+
id: string;
78+
name?: string;
79+
age?: number;
80+
};
81+
82+
type User = Concrete<MaybeUser>;
83+
// ^?
84+
```
85+
86+
## Key Remapping via `as`
87+
88+
TypeScript 4.1 이상에서는 매핑된 타입에 `as` 절을 사용해서 매핑된 타입의 키를 다시 매핑할 수 있습니다.
89+
90+
```ts
91+
type MappedTypeWithNewProperties<Type> = {
92+
[Properties in keyof Type as NewKeyType]: Type[Properties]
93+
}
94+
```
95+
96+
[템플릿 리터럴 타입](/docs/handbook/2/template-literal-types.html)과 같은 기능을 활용해서 이전 프로퍼티에서 새로운 프로퍼티 이름을 만들 수 있습니다.
97+
98+
```ts twoslash
99+
type Getters<Type> = {
100+
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
101+
};
102+
103+
interface Person {
104+
name: string;
105+
age: number;
106+
location: string;
107+
}
108+
109+
type LazyPerson = Getters<Person>;
110+
// ^?
111+
```
112+
113+
조건부 타입을 통해 `never`를 생성해서 키를 필터링할 수 있습니다.
114+
115+
```ts twoslash
116+
// 'kind' 프로퍼티를 제거합니다
117+
type RemoveKindField<Type> = {
118+
[Property in keyof Type as Exclude<Property, "kind">]: Type[Property]
119+
};
120+
121+
interface Circle {
122+
kind: "circle";
123+
radius: number;
124+
}
125+
126+
type KindlessCircle = RemoveKindField<Circle>;
127+
// ^?
128+
```
129+
130+
`string | number | symbol` 의 조합뿐만 아니라 모든 타입의 조합을 임의로 매핑할 수 있습니다.
131+
132+
```ts twoslash
133+
type EventConfig<Events extends { kind: string }> = {
134+
[E in Events as E["kind"]]: (event: E) => void;
135+
}
136+
137+
type SquareEvent = { kind: "square", x: number, y: number };
138+
type CircleEvent = { kind: "circle", radius: number };
139+
140+
type Config = EventConfig<SquareEvent | CircleEvent>
141+
// ^?
142+
```
143+
144+
### Further Exploration
145+
146+
매핑된 타입은 타입 조작 섹션의 다른 기능들과 잘 동작합니다. 예를 들어 객체의 `pii` 프로퍼티가 `true`로 설정되어 있는지에 따라 `true` 혹은 `false`를 반환하는 [조건부 타입을 사용한 매핑된 타입](/docs/handbook/2/conditional-types.html)이 있습니다.
147+
148+
```ts twoslash
149+
type ExtractPII<Type> = {
150+
[Property in keyof Type]: Type[Property] extends { pii: true } ? true : false;
151+
};
152+
153+
type DBFields = {
154+
id: { format: "incrementing" };
155+
name: { type: string; pii: true };
156+
};
157+
158+
type ObjectsNeedingGDPRDeletion = ExtractPII<DBFields>;
159+
// ^?
160+
```

0 commit comments

Comments
 (0)