@@ -5,17 +5,17 @@ permalink: /docs/handbook/release-notes/typescript-4-0.html
5
5
oneline : TypeScript 4.0 Release Notes
6
6
---
7
7
8
- ## Variadic Tuple Types
8
+ ## ๊ฐ๋ณ ์ธ์ ํํ ์ ํ ( Variadic Tuple Types)
9
9
10
- Consider a function in JavaScript called ` concat ` that takes two array or tuple types and concatenates them together to make a new array .
10
+ ๋ ๊ฐ์ ๋ฐฐ์ด ํน์ ํํ ํ์
์ ์ฐ๊ฒฐํ์ฌ ์๋ก์ด ๋ฐฐ์ด์ ๋ง๋๋ JavaScript์ ` concat ` ํจ์์ ๋ํด์ ์๊ฐํด๋ด
์๋ค .
11
11
12
12
``` js
13
13
function concat (arr1 , arr2 ) {
14
14
return [... arr1, ... arr2];
15
15
}
16
16
```
17
17
18
- Also consider ` tail ` , that takes an array or tuple, and returns all elements but the first .
18
+ ๋ํ, ๋ฐฐ์ด์ด๋ ํํ์ ๋ณ์๋ก ์
๋ ฅ๋ฐ์ ์ฒซ ๋ฒ์งธ ์์๋ฅผ ์ ์ธํ ๋ชจ๋ ์์๋ฅผ ๋ฐํํด์ฃผ๋ ` tail ` ํจ์์ ๋ํด์๋ ์๊ฐํด๋ด
์๋ค .
19
19
20
20
``` js
21
21
function tail (arg ) {
@@ -24,9 +24,9 @@ function tail(arg) {
24
24
}
25
25
```
26
26
27
- How would we type either of these in TypeScript ?
27
+ TypeScript์์๋ ์ด ๋ ํจ์์ ํ์
์ ์ด๋ป๊ฒ ์ ์ํ ์ ์์๊น์ ?
28
28
29
- For ` concat ` , the only valid thing we could do in older versions of the language was to try and write some overloads .
29
+ ` concat ` ์ ๊ฒฝ์ฐ, ์ด์ ๋ฒ์ ์์๋ ์ฌ๋ฌ ๊ฐ์ ์ค๋ฒ๋ก๋๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ์ด ์ ์ผํ์ต๋๋ค .
30
30
31
31
``` ts
32
32
function concat(arr1 : [], arr2 : []): [];
@@ -38,8 +38,8 @@ function concat<A, B, C, D, E>(arr1: [A, B, C, D, E], arr2: []): [A, B, C, D, E]
38
38
function concat<A , B , C , D , E , F >(arr1 : [A , B , C , D , E , F ], arr2 : []): [A , B , C , D , E , F ];)
39
39
```
40
40
41
- Uh ...okay, that's...seven overloads for when the second array is always empty .
42
- Let's add some for when ` arr2 ` has one argument .
41
+ ์ ... ๋ค, ๋ ๋ฒ์งธ์ ๋ฐฐ์ด์ด ํญ์ ๋น์ด์๋ ๊ฒฝ์ฐ ์์ฑ๋ 7๊ฐ์ ์ค๋ฒ๋ก๋๋ค์
๋๋ค .
42
+ ์ด๋, ` arr2 ` ๊ฐ ํ๋์ ์ธ์๋ฅผ ๊ฐ์ง๊ณ ์๋ ๊ฒฝ์ฐ๋ฅผ ์ถ๊ฐํด๋ด
์๋ค .
43
43
44
44
<!-- prettier-ignore -->
45
45
``` ts
@@ -52,26 +52,27 @@ function concat<A1, B1, C1, D1, E1, A2>(arr1: [A1, B1, C1, D1, E1], arr2: [A2]):
52
52
function concat<A1 , B1 , C1 , D1 , E1 , F1 , A2 >(arr1 : [A1 , B1 , C1 , D1 , E1 , F1 ], arr2 : [A2 ]): [A1 , B1 , C1 , D1 , E1 , F1 , A2 ];
53
53
```
54
54
55
- We hope it's clear that this is getting unreasonable .
56
- Unfortunately, you'd also end up with the same sorts of issues typing a function like ` tail ` .
55
+ ์ด๊ฒ์ด ์ง๋์น๋ค๋ ๊ฒ์ด ๋ถ๋ช
ํด์ง๊ธฐ๋ฅผ ๋ฐ๋๋๋ค .
56
+ ์ํ๊น๊ฒ๋, ` tail ` ๊ณผ ๊ฐ์ ํจ์๋ฅผ ํ์ดํํ ๋ ์ด์ ๊ฐ์ ๋น์ทํ ์ข
๋ฅ์ ๋ฌธ์ ์ ์ง๋ฉดํ๊ฒ ๋ ๊ฒ์
๋๋ค .
57
57
58
- This is another case of what we like to call "death by a thousand overloads", and it doesn't even solve the problem generally.
59
- It only gives correct types for as many overloads as we care to write.
60
- If we wanted to make a catch-all case, we'd need an overload like the following:
58
+
59
+ ์ด๊ฒ์ "์ฒ ๊ฐ์ ์ค๋ฒ๋ก๋๋ก ์ธํ ์ฃฝ์(death by a thousand overloads)"์ด๋ผ๊ณ ๋ถ๋ฅด๊ณ ์ถ์ ๋๋ค๋ฅธ ๊ฒฝ์ฐ์ด๋ฉฐ, ์ผ๋ฐ์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ง๋ ์์ต๋๋ค.
60
+ ์ฐ๋ฆฌ๊ฐ ์์ฑํ๊ณ ์ํ๋๋งํผ์ ์ค๋ฒ๋ก๋์ ํํด์๋ง ์ฌ๋ฐ๋ฅธ ํ์
์ ์ ๊ณตํฉ๋๋ค.
61
+ ํฌ๊ด์ ์ธ ์ผ์ด์ค๋ฅผ ๋ง๋ค๊ณ ์ถ๋ค๋ฉด, ๋ค์๊ณผ ๊ฐ์ ์ค๋ฒ๋ก๋๊ฐ ํ์ํฉ๋๋ค.
61
62
62
63
``` ts
63
64
function concat<T , U >(arr1 : T [], arr2 : U []): Array <T | U >;
64
65
```
65
66
66
- But that signature doesn't encode anything about the lengths of the input, or the order of the elements, when using tuples .
67
+ ๊ทธ๋ฌ๋ ํด๋น ์๊ทธ๋์ฒ๋ ํํ์ ์ฌ์ฉํ ๋ ์
๋ ฅ์ ๊ธธ์ด๋ ์์์ ์์์ ๋ํ ์ด๋ค ๊ฒ๋ ์ธ์ฝ๋ฉํ์ง ์์ต๋๋ค .
67
68
68
- TypeScript 4.0 brings two fundamental changes, along with inference improvements, to make typing these possible .
69
+ TypeScript 4.0์ ์ถ๋ก ๊ฐ์ ๊ณผ ํจ๊ป ๋ ๊ฐ์ง ํต์ฌ์ ์ธ ๋ณํ๋ฅผ ๊ฐ์ ธ์ ์ด๋ฌํ ํ์ดํ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค .
69
70
70
- The first change is that spreads in tuple type syntax can now be generic .
71
- This means that we can represent higher-order operations on tuples and arrays even when we don't know the actual types we're operating over .
72
- When generic spreads are instantiated (or, replaced with a real type) in these tuple types, they can produce other sets of array and tuple types .
71
+ ์ฒซ ๋ฒ์งธ ๋ณํ๋ ํํ ํ์
๊ตฌ๋ฌธ์ ํ์ฅ ์ฐ์ฐ์์์ ์ ๋๋ฆญ ํ์
์ ์ฌ์ฉํ ์ ์๋ค๋ ์ ์
๋๋ค .
72
+ ์ด ๊ฒ์ ์ฐ๋ฆฌ๊ฐ ์๋ํ๋ ์ค์ ํ์
์ ๋ชจ๋ฅด๋๋ผ๋ ํํ๊ณผ ๋ฐฐ์ด์ ๋ํด ๊ณ ์ฐจํจ์๋ฅผ ํํํ ์ ์๋ค๋ ๋ป์
๋๋ค .
73
+ ์ด๋ฌํ ํํ ํ์
์์ ์ ๋๋ฆญ ํ์ฅ ์ฐ์ฐ์๊ฐ ์ธ์คํด์คํ(ํน์, ์ค์ ํ์
์ผ๋ก ๋์ฒด)๋๋ฉด ๋๋ค๋ฅธ ๋ฐฐ์ด์ด๋ ํํ ํ์
์ธํธ๋ฅผ ์์ฐํ ์ ์์ต๋๋ค .
73
74
74
- For example, that means we can type function like ` tail ` , without our " death by a thousand overloads" issue .
75
+ ์๋ฅผ ๋ค์ด, ` tail ` ๊ฐ์ ํจ์๋ฅผ "์ฒ ๊ฐ์ ์ค๋ฒ๋ก๋๋ก ์ธํ ์ฃฝ์( death by a thousand overloads)"์ด์ ์์ด ํ์ดํ ํ ์ ์๊ฒ ๋ฉ๋๋ค .
75
76
76
77
``` ts
77
78
function tail<T extends any []>(arr : readonly [any , ... T ]) {
@@ -83,41 +84,41 @@ const myTuple = [1, 2, 3, 4] as const;
83
84
const myArray = [" hello" , " world" ];
84
85
85
86
const r1 = tail (myTuple );
86
- // ^?
87
+ // ^ = const r1: [2, 3, 4]
87
88
88
89
const r2 = tail ([... myTuple , ... myArray ] as const );
89
- // ^?
90
+ // ^ = const r2: [2, 3, 4, ...string[]]
90
91
```
91
92
92
- The second change is that rest elements can occur anywhere in a tuple - not just at the end!
93
+ ๋ ๋ฒ์งธ ๋ณํ๋ ๋๋จธ์ง ์์๊ฐ ๋๋ฟ๋ง ์๋๋ผ ํํ์ ์ด๋ ๊ณณ์์๋ ๋ฐ์ํ ์ ์๋ค๋ ๊ฒ์
๋๋ค.
93
94
94
95
``` ts
95
96
type Strings = [string , string ];
96
97
type Numbers = [number , number ];
97
98
98
99
type StrStrNumNumBool = [... Strings , ... Numbers , boolean ];
99
- // ^?
100
+ // ^ = type StrStrNumNumBool = [string, string, number, number, boolean]
100
101
```
101
102
102
- Previously, TypeScript would issue an error like the following :
103
+ ์ด์ ์๋, TypeScript๋ ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๋ฅผ ์์ฑํ์์ต๋๋ค :
103
104
104
105
```
105
106
A rest element must be last in a tuple type.
106
107
```
107
108
108
- But with TypeScript 4.0, this restriction is relaxed .
109
+ TypeScript 4.0์์๋ ์ด๋ฌํ ์ ํ์ด ์ํ๋์์ต๋๋ค .
109
110
110
- Note that in cases when we spread in a type without a known length, the resulting type becomes unbounded as well, and all the following elements factor into the resulting rest element type .
111
+ ๊ธธ์ด๊ฐ ์ ํด์ง์ง ์์ ํ์
์ ํ์ฅํ๋ ค๊ณ ํ ๋, ๊ฒฐ๊ณผ์ ํ์
์ ์ ํ๋์ง ์์ผ๋ฉฐ, ๋ค์ ๋ชจ๋ ์์๊ฐ ๊ฒฐ๊ณผ์ ๋๋จธ์ง ์์ ํ์
์ ํฌํจ๋๋ ์ ์ ์ ์ํ์๊ธฐ ๋ฐ๋๋๋ค .
111
112
112
113
``` ts
113
114
type Strings = [string , string ];
114
115
type Numbers = number [];
115
116
116
117
type Unbounded = [... Strings , ... Numbers , boolean ];
117
- // ^?
118
+ // ^ = type Unbounded = [string, string, ...(number | boolean)[]]
118
119
```
119
120
120
- By combining both of these behaviors together, we can write a single well-typed signature for ` concat ` :
121
+ ์ด ๋ ๊ฐ์ง ๋์์ ํจ๊ป ๊ฒฐํฉํ์ฌ, ` concat ` ์ ๋ํด ํ์
์ด ์ ๋๋ก ์ ์๋ ์๊ทธ๋์ฒ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
121
122
122
123
``` ts
123
124
type Arr = readonly any [];
@@ -127,20 +128,20 @@ function concat<T extends Arr, U extends Arr>(arr1: T, arr2: U): [...T, ...U] {
127
128
}
128
129
```
129
130
130
- While that one signature is still a bit lengthy, it's just one signature that doesn't have to be repeated, and it gives predictable behavior on all arrays and tuples .
131
+ ํ๋์ ์๊ทธ๋์ฒ๊ฐ ์กฐ๊ธ ๊ธธ๋๋ผ๋, ๋ฐ๋ณตํ ํ์๊ฐ ์๋ ํ๋์ ์๊ทธ๋์ฒ์ผ๋ฟ์ด๋ฉฐ, ๋ชจ๋ ๋ฐฐ์ด๊ณผ ํํ์์ ์์ธก๊ฐ๋ฅํ ํ๋์ ์ ๊ณตํฉ๋๋ค .
131
132
132
- This functionality on its own is great, but it shines in more sophisticated scenarios too .
133
- For example, consider a function to [ partially apply arguments ] ( https://en.wikipedia.org/wiki/Partial_application ) called ` partialCall ` .
134
- ` partialCall ` takes a function - let's call it ` f ` - along with the initial few arguments that ` f ` expects .
135
- It then returns a new function that takes any other arguments that ` f ` still needs, and calls ` f ` when it receives them .
133
+ ์ด ๊ธฐ๋ฅ์ ๊ทธ ์์ฒด๋ง์ผ๋ก๋ ํ๋ฅญํ์ง๋ง, ์กฐ๊ธ ๋ ์ ๊ตํ ์๋๋ฆฌ์ค์์๋ ๋น์ ๋ฐํฉ๋๋ค .
134
+ ์๋ฅผ ๋ค์ด, [ ํจ์์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ถ๋ถ์ ์ผ๋ก ์ ์ฉํ์ฌ ์๋ก์ด ํจ์๋ฅผ ๋ฐํํ๋ ] ( https://en.wikipedia.org/wiki/Partial_application ) ` partialCall ` ํจ์๊ฐ ์๋ค๊ณ ์๊ฐํด๋ด
์๋ค .
135
+ ` partialCall ` ์ ๋ค์๊ณผ ๊ฐ์ ํจ์๋ฅผ ๊ฐ์ง๋๋ค. - ` f ` ๊ฐ ์์ํ๋ ๋ช ๊ฐ์ง ์ธ์์ ํจ๊ป ` f ` ๋ผ๊ณ ์ง์ ํ๊ฒ ์ต๋๋ค .
136
+ ๊ทธ ํ, ` f ` ๊ฐ ์ฌ์ ํ ํ์๋กํ๋ ๋ค๋ฅธ ์ธ์๋ฅผ ๊ฐ์ง๊ณ , ๊ทธ๊ฒ์ ๋ฐ์ ๋ ` f ` ๋ฅผ ํธ์ถํ๋ ์๋ก์ด ํจ์๋ฅผ ๋ฐํํฉ๋๋ค .
136
137
137
138
``` js
138
139
function partialCall (f , ... headArgs ) {
139
140
return (... tailArgs ) => f (... headArgs, ... tailArgs);
140
141
}
141
142
```
142
143
143
- TypeScript 4.0 improves the inference process for rest parameters and rest tuple elements so that we can type this and have it "just work" .
144
+ TypeScript 4.0์ ๋๋จธ์ง ํ๋ผ๋ฏธํฐ๋ค๊ณผ ํํ ์์๋ค์ ๋ํ ์ถ๋ก ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ ํ์ฌ ํ์
์ ์ง์ ํ ์ ์๊ณ "๊ทธ๋ฅ ๋์"ํ๋๋ก ํ ์ ์์ต๋๋ค .
144
145
145
146
``` ts
146
147
type Arr = readonly unknown [];
@@ -153,7 +154,7 @@ function partialCall<T extends Arr, U extends Arr, R>(
153
154
}
154
155
```
155
156
156
- In this case , ` partialCall ` understands which parameters it can and can't initially take, and returns functions that appropriately accept and reject anything left over .
157
+ ์ด ๊ฒฝ์ฐ , ` partialCall ` ์ ์ฒ์์ ์ทจํ ์ ์๋ ํ๋ผ๋ฏธํฐ์ ํ ์ ์๋ ํ๋ผ๋ฏธํฐ๋ฅผ ํ์
ํ๊ณ , ๋จ์ ๊ฒ๋ค์ ์ ์ ํ ์์ฉํ๊ณ ๊ฑฐ๋ถํ๋ ํจ์๋ค์ ๋ฐํํฉ๋๋ค .
157
158
158
159
``` ts
159
160
// @errors: 2345 2554 2554 2345
@@ -169,26 +170,29 @@ function partialCall<T extends Arr, U extends Arr, R>(
169
170
const foo = (x : string , y : number , z : boolean ) => {};
170
171
171
172
const f1 = partialCall (foo , 100 );
173
+ // [Error] Argument of type 'number' is not assignable to parameter of type 'string'.
172
174
173
175
const f2 = partialCall (foo , " hello" , 100 , true , " oops" );
176
+ // [Error] Expected 4 arguments, but got 5.
174
177
175
- // This works !
178
+ // ์๋ํฉ๋๋ค !
176
179
const f3 = partialCall (foo , " hello" );
177
- // ^?
180
+ // ^ = const f3: (y: number, z: boolean) => void
178
181
179
- // What can we do with f3 now ?
182
+ // f3์ผ๋ก ๋ญ ํ ์ ์์๊น์ ?
180
183
181
- // Works !
184
+ // ์๋ํฉ๋๋ค !
182
185
f3 (123 , true );
183
-
186
+ // [Error] Expected 2 arguments, but got 0.
184
187
f3 ();
185
188
186
189
f3 (123 , " hello" );
190
+ // [Error] Argument of type 'string' is not assignable to parameter of type 'boolean'.
187
191
```
188
192
189
- Variadic tuple types enable a lot of new exciting patterns, especially around function composition .
190
- We expect we may be able to leverage it to do a better job type-checking JavaScript's built-in ` bind ` method .
191
- A handful of other inference improvements and patterns also went into this, and if you're interested in learning more, you can take a look at [ the pull request] ( https://github.com/microsoft/TypeScript/pull/39094 ) for variadic tuples .
193
+ ๊ฐ๋ณ ์ธ์ ํํ ํ์
์ ํนํ ๊ธฐ๋ฅ ๊ตฌ์ฑ๊ณผ ๊ด๋ จํ์ฌ ๋ง์ ์๋ก์ด ํฅ๋ฏธ๋ก์ด ํจํด์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค .
194
+ ์ฐ๋ฆฌ๋ JavaScript์ ๋ด์ฅ๋ ` bind ` ๋ฉ์๋์ ํ์
์ฒดํน์ ๋ ์ํ๊ธฐ ์ํด ์ด๋ฅผ ํ์ฉํ ์ ์์ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํฉ๋๋ค .
195
+ ๋ช ๊ฐ์ง ๋ค๋ฅธ ์ถ๋ก ๊ฐ์ ๋ฐ ํจํด๋ค๋ ์ฌ๊ธฐ์ ํฌํจ๋์ด์์ผ๋ฉฐ, ๊ฐ๋ณ ์ธ์ ํํ์ ๋ํด ๋ ์์๋ณด๊ณ ์ถ๋ค๋ฉด, [ the pull request] ( https://github.com/microsoft/TypeScript/pull/39094 ) ๋ฅผ ์ฐธ๊ณ ํด๋ณด์ธ์ .
192
196
193
197
## Labeled Tuple Elements
194
198
0 commit comments