|
| 1 | +# 15장 |
| 2 | + |
| 3 | +## 15.1 매핑된 타입 |
| 4 | + |
| 5 | +타입스크립트의 매핑된 타입은 다른 타입을 가져와서 해당 타입의 각 속성에 대해 일부 작업을 수행하는 타입이다. 매핑된 타입은 키 집합의 각 키에 대한 새로운 속성을 만들어 새로운 타입을 생성한다. |
| 6 | + |
| 7 | +```ts |
| 8 | +type Animals = "dog" | "cat" | "rabbit"; |
| 9 | + |
| 10 | +type AnimalCounts = { |
| 11 | + [K in Animals]: number; |
| 12 | +}; |
| 13 | + |
| 14 | +// 다음과 같다 |
| 15 | +// { |
| 16 | +// "dog": number; |
| 17 | +// "cat": number; |
| 18 | +// "rabbit": number; |
| 19 | +// } |
| 20 | +``` |
| 21 | + |
| 22 | +매핑된 타입은 인덱스 시그니처와 유사한 구문을 사용하지만 정적 키 타입을 사용하는 대신 in을 사용해 다른 타입으로부터 계산된 타입을 사용한다. |
| 23 | + |
| 24 | +### 타입에서 매핑된 타입 |
| 25 | + |
| 26 | +```ts |
| 27 | +interface Animals = { |
| 28 | + "dog": string; |
| 29 | + "cat": boolean; |
| 30 | + "rabbit": number; |
| 31 | +}; |
| 32 | + |
| 33 | +type AnimalCounts = { |
| 34 | + [K in keyof Animals]: Animals[K] | null; |
| 35 | +}; |
| 36 | + |
| 37 | +// 다음과 같다 |
| 38 | +// { |
| 39 | +// "dog": string | null; |
| 40 | +// "cat": boolean | null; |
| 41 | +// "rabbit": number | null; |
| 42 | +// } |
| 43 | +``` |
| 44 | + |
| 45 | +매핑된 타입의 각 멤버는 `Animals[K]`로 참조할 수 있다. 매핑된 타입은 멤버 집합을 한 번 정의하고 필요한 만큼 여러 번 새로운 버전을 다시 생성할 수 있다. |
| 46 | + |
| 47 | +## 15.2 조건부 타입 |
| 48 | + |
| 49 | +조건부 타입에서 논리적 검사는 항상 `extends`의 왼쪽 타입이 오른쪽 타입이 되는지 또는 할당 가능한지 여부에 있다. |
| 50 | + |
| 51 | +### 제네릭 조건부 타입 |
| 52 | + |
| 53 | +```ts |
| 54 | +interface QueryOptions { |
| 55 | + throwIfNotFound: boolean; |
| 56 | +} |
| 57 | + |
| 58 | +type QueryResult<Options extends QueryOptions> = { |
| 59 | + Options["throwIfNotFound"] extends true ? string : string | undefined; |
| 60 | +} |
| 61 | +``` |
| 62 | +
|
| 63 | +`QueryResult` 타입은 `Options["throwIfNotFound"]`가 `true`인 것으로 명확하게 밝혀지면 더 좁은 `string` 타입이 되도록 모델링한다. |
| 64 | +
|
| 65 | +## 15.3 never |
| 66 | +
|
| 67 | +### never와 조건부 타입 |
| 68 | +
|
| 69 | +제네릭 조건부 타입은 일반적으로 유니언에서 타입을 필터링하기 위해 `never`를 사용한다. |
| 70 | +
|
| 71 | +```ts |
| 72 | +type OnlyString<T> = T extends string ? T : never; |
| 73 | + |
| 74 | +type RedOrBlue = OnlyString<"red" | "blue" | 0 | false>; // "red" | "blue" |
| 75 | +``` |
| 76 | + |
| 77 | +## 15.4 템플릿 리터럴 타입 |
| 78 | + |
| 79 | +```ts |
| 80 | +type Greeting = "Hello${string}"; |
| 81 | + |
| 82 | +let matches: Greeting = "Hello world"; |
| 83 | +let outOfOrder: Greeting = "World hello"; // Error |
| 84 | +``` |
| 85 | + |
| 86 | +템플릿 리터럴 타입은 문자열 타입이 패턴에 맞는지를 나타낸다. 템플릿 리터럴 타입인 `Greeting`은 문자열이 Hello로 시작해야 함을 뜻한다. 템플릿 리터럴 타입은 제한된 허용 문자열 집합과 일치해야 하는 문자열을 설명하는데 매우 유용하다. |
| 87 | + |
| 88 | +```ts |
| 89 | +type Brightness = "dark" | "light"; |
| 90 | +type Color = "blue" | "red"; |
| 91 | + |
| 92 | +type BrightnessAndColor = `${Brightness}-${Color}`; |
| 93 | + |
| 94 | +let colorOk: BrightnessAndColor = "dark-blue"; |
| 95 | +``` |
| 96 | + |
| 97 | +`BrightnessAndColor`는 `Brightness`로 시작하고 `Color`로 끝나며 그 사이에 하이픈(-)이 있는 문자열만 일치한다. |
| 98 | + |
| 99 | +### 고유 문자열 조작 타입 |
| 100 | + |
| 101 | +문자열 타입 작업을 지원하기 위해 타입스크립트는 문자열을 가져와 문자열에 일부 조작을 젹용하는 고유 제네릭 유틸리티 타입을 제공한다. |
| 102 | + |
| 103 | +- Uppercase |
| 104 | +- Lowercase |
| 105 | +- Capitalize |
| 106 | +- Uncapitalize |
| 107 | + |
| 108 | +```ts |
| 109 | +type FormalGreeting = Capitalize<"hello">; // 타입 : "Hello" |
| 110 | +``` |
| 111 | + |
| 112 | +### 템플릿 리터럴 키 |
| 113 | + |
| 114 | +```ts |
| 115 | +type Key = "location" | "name" | "year"; |
| 116 | + |
| 117 | +type ExistenceChecks = { |
| 118 | + [K in "check${Capitalize<Key>}"]: () => boolean; |
| 119 | +}; |
| 120 | + |
| 121 | +// 다음과 같다. |
| 122 | +// { |
| 123 | +// "checkLocation": () => boolean; |
| 124 | +// "checkName": () => boolean; |
| 125 | +// "checkYear": () => boolean; |
| 126 | +// } |
| 127 | +``` |
0 commit comments