You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 12, 2022. It is now read-only.
One common task is to take an existing type and make each of its properties entirely optional.
72
+
Let's say we have a `Person:
72
73
73
74
```ts
74
75
interfacePerson {
@@ -78,8 +79,7 @@ interface Person {
78
79
}
79
80
```
80
81
81
-
Much of the time, we want to take an existing type and make each of its properties entirely optional.
82
-
With `Person`, we might write the following:
82
+
A partial verion of it can would be:
83
83
84
84
```ts
85
85
interfacePartialPerson {
@@ -89,78 +89,30 @@ interface PartialPerson {
89
89
}
90
90
```
91
91
92
-
Notice we had to define a completely new type.
93
-
94
-
Similarly, we might want to perform a shallow freeze of an object:
95
-
96
-
```ts
97
-
interfaceFrozenPerson {
98
-
readonly name:string;
99
-
readonly age:number;
100
-
readonly location:string;
101
-
}
102
-
```
103
-
104
-
Or we might want to create a related type where all the properties are `Promise`s.
92
+
with Mapped types, `PartialPerson` can be written as a generalized transformation on the type `Person` as:
105
93
106
94
```ts
107
-
interfaceBooleanifiedPerson {
108
-
name:boolean;
109
-
age:boolean;
110
-
location:boolean;
111
-
}
112
-
```
113
-
114
-
Notice all this repetition - ideally, much of the same information in each variant of `Person` could have been shared.
115
-
116
-
Let's take a look at how we could write `BooleanifiedPerson` with a *mapped type*.
117
-
118
-
```ts
119
-
typeBooleanifiedPerson= {
120
-
[Pin"name"|"age"|"location"]:boolean
95
+
typePartial<T> = {
96
+
[PinkeyofT]?:T[P];
121
97
};
122
-
```
123
98
124
-
Mapped types are produced by taking a union of literal types, and compute a set of properties for a new object type.
125
-
They're like [list comprehensions in Python](https://docs.python.org/2/tutorial/datastructures.html#nested-list-comprehensions), but instead of producing new elements in a list, they produce new properties in a type.
126
-
127
-
In the above example, TypeScript uses each literal type in `"name" | "age" | "location"`, and produces a property of that name (e.g. properties named `name`, `age`, and `location`).
128
-
`P` gets bound to each of those literal types (even though it's not used in this example), and gives the property the type `boolean`.
129
-
130
-
Right now, this new form doesn't look ideal, but we can use the `keyof` operator to cut down on the typing:
131
-
132
-
```ts
133
-
typeBooleanifiedPerson= {
134
-
[PinkeyofPerson]:boolean
135
-
};
99
+
typePartialPerson=Partial<Person>;
136
100
```
137
101
138
-
And then we can generalize it:
139
-
140
-
```ts
141
-
typeBooleanify<T> = {
142
-
[PinkeyofT]:boolean
143
-
};
144
-
145
-
typeBooleanifiedPerson=Booleanify<Person>;
146
-
```
102
+
Mapped types are produced by taking a union of literal types, and computing a set of properties for a new object type.
103
+
They're like [list comprehensions in Python](https://docs.python.org/2/tutorial/datastructures.html#nested-list-comprehensions), but instead of producing new elements in a list, they produce new properties in a type.
147
104
148
-
With mapped types, we no longer have to create new partial or readonly variants of existing types either.
105
+
In addition to `Partial`, Mapped Types can enable expressing many usueful transfomrations on types:
149
106
150
107
```ts
151
-
// Keep types the same, but make every property optional.
152
-
typePartial<T> = {
153
-
[PinkeyofT]?:T[P];
154
-
};
155
-
156
108
// Keep types the same, but make each property to be read-only.
157
109
typeReadonly<T> = {
158
110
readonly [PinkeyofT]:T[P];
159
111
};
160
112
161
-
// Same property names, but make the value a promise instead of a concreate one
162
-
typeDefered<T> = {
163
-
readonly[PinkeyofT]:Promise<T[P]>;
113
+
// Same property names, but make the value a promise instead of a concrete one
114
+
typeDeferred<T> = {
115
+
[PinkeyofT]:Promise<T[P]>;
164
116
};
165
117
166
118
// Wrap proxies around properties of T
@@ -169,26 +121,23 @@ type Proxify<T> = {
169
121
};
170
122
```
171
123
172
-
So instead of defining a completely new type like `PartialPerson`, we can just write `Partial<Person>`.
173
-
Likewise, instead of repeating ourselves with `FrozenPerson`, we can just write `Readonly<Person>`!
174
-
175
124
## `Partial`, `Readonly`, `Record`, and `Pick`
176
125
177
-
`Partial` and `Readonly`, as described earlier, are very useful construct.
126
+
`Partial` and `Readonly`, as described earlier, are very useful constructs.
178
127
You can use them to describe some common JS routines like:
179
128
180
129
```ts
181
130
function assign<T>(obj:T, props:Partial<T>):void;
182
131
function freeze<T>(obj:T):Readonly<T>;
183
132
```
184
133
185
-
For that, they are now included by default in the standard library.
134
+
Because of that, they are now included by default in the standard library.
186
135
187
136
We're also including two other utility types as well: `Record` and `Pick`.
188
137
189
138
```ts
190
139
// From T pick a set of properties K
191
-
function pick<T, KextendskeyofT>(obj:T, ...keys:K[]):Pick<T, K>;
var newObj = {...obj, z: 3, y: 4}; // { x: number, y:number, x: number }
225
175
```
226
176
227
-
The order of specifying spread operations decides what properties end up in the resulting object;
177
+
The order of specifying spread operations determines what properties end up in the resulting object;
228
178
properties in later spreads "win out" over previously created properties.
229
179
230
180
Object rests are the dual of object spreads, in that they can extract any extra properties that don't get picked up when destructuring an element:
@@ -283,12 +233,20 @@ Compiling and running the output should result in the correct behavior on an ES3
283
233
284
234
# Support for external helpers library (`tslib`)
285
235
286
-
TypeScript injects a handful of helper functions such as `__extends` for inheritance, `__assign` for spread operator in JSX, and `__awaiter` for async functions.
287
-
Previously there were two options either 1. inject helpers in *every* file that needs them or 2. no helpers at all with `--noEmitHelpers`.
236
+
TypeScript injects a handful of helper functions such as `__extends` for inheritance, `__assign` for spread operator in object literals and JSX elements, and `__awaiter` for async functions.
237
+
238
+
Previously there were two options either:
239
+
240
+
1. inject helpers in *every* file that needs them, or
241
+
2. no helpers at all with `--noEmitHelpers`.
242
+
243
+
The two options left more to be desired;
244
+
bundling the helpers in every file was a pain point for customers trying to keep their package size small.
245
+
And not including helpers, meant customers had to maintain their own helpers library.
288
246
289
247
TypeScript 2.1 allows for including these files in your project once in a separate module, and the compiler will emit imports to them as needed.
290
248
291
-
First, install the [`tslib`](https://github.com/Microsoft/tslib):
249
+
First, install the [`tslib`](https://github.com/Microsoft/tslib) utility library:
292
250
293
251
```sh
294
252
npm install tslib
@@ -300,17 +258,13 @@ Second, compile your files using `--importHelpers`:
300
258
tsc --module commonjs --importHelpers a.ts
301
259
```
302
260
303
-
##### Example
304
-
305
-
For input using the object rest `__assign` helper:
261
+
So given the following input, the resulting `.js` file will include an import to `tslib` and use the `__assign` helper from it instead of inlining it.
306
262
307
263
```ts
308
264
exportconst o = { a: 1, name: "o" };
309
265
exportconst copy = { ...o };
310
266
```
311
267
312
-
The resulting `.js` file will include an import to `tslib` and use the `__assign` helper from it instead of inlining it.
313
-
314
268
```js
315
269
"use strict";
316
270
var tslib_1 =require("tslib");
@@ -325,7 +279,7 @@ This was to avoid typos and prevent users from using modules incorrectly.
325
279
326
280
However, a lot of the time, you might just want to import an existing module that may not have its own `.d.ts` file.
327
281
Previously this was an error.
328
-
Starting with TypeScript 2.1 this should get much easier.
282
+
Starting with TypeScript 2.1 this is now much easier.
329
283
330
284
With TypeScript 2.1, you can import a JavaScript module without needing a type declaration.
331
285
A type declaration (such as `declare module "foo" { ... }` or `node_modules/@types/foo`) still takes priority if it exists.
@@ -339,9 +293,19 @@ An import to a module with no declaration file will still be flagged as an error
339
293
import { x } from"asdf";
340
294
```
341
295
296
+
# Support for `--target ES2016`, `--target ES2017` and `--target ESNext`
297
+
298
+
TypeScript 2.1 supports three new target values `--target ES2016`, `--target ES2017` and `--target ESNext`.
299
+
300
+
Using target `--target ES2016` will instruct the compiler not to transform ES2016-specific features, e.g. `**` operator.
301
+
302
+
Similarly, `--target ES2017` will instruct the compiler not to transform ES2017-specific features like `async`/`await`.
Previously, if TypeScript can't figure out the type of a variable, it will choose the `any` type.
308
+
Previously, if TypeScript couldn't figure out the type of a variable, it would choose the `any` type.
345
309
346
310
```ts
347
311
let x; // implicitly 'any'
@@ -380,7 +344,7 @@ x.toLowerCase();
380
344
The same sort of tracking is now also done for empty arrays.
381
345
382
346
A variable declared with no type annotation and an initial value of `[]` is considered an implicit `any[]` variable.
383
-
Each following `x.push(value)`, `x.unshift(value)` or `x[n] = value` operation _evolves_ the type of the variable in accordance with what elements are added to it.
347
+
However, each subsequent `x.push(value)`, `x.unshift(value)` or `x[n] = value` operation *evolves* the type of the variable in accordance with what elements are added to it.
384
348
385
349
```ts
386
350
function f1() {
@@ -406,7 +370,7 @@ function f2() {
406
370
## Implicit any errors
407
371
408
372
One great benefit of this is that you'll see *way fewer* implicit `any` errors when running with `--noImplicitAny`.
409
-
Implicit `any` errors are only reported when the compiler is unable to know the type of a available without a type annotation.
373
+
Implicit `any` errors are only reported when the compiler is unable to know the type of a variable without a type annotation.
410
374
411
375
##### Example
412
376
@@ -423,7 +387,7 @@ function f3() {
423
387
# Better inference for literal types
424
388
425
389
String, numeric and boolean literal types (e.g. `"abc"`, `1`, and `true`) were previously inferred only in the presence of an explicit type annotation.
426
-
Starting with TypeScript 2.1, literal types are *always* inferred by default.
390
+
Starting with TypeScript 2.1, literal types are *always* inferred for `const` variables and `readonly` properties.
427
391
428
392
The type inferred for a `const` variable or `readonly` property without a type annotation is the type of the literal initializer.
429
393
The type inferred for a `let` variable, `var` variable, parameter, or non-`readonly` property with an initializer and no type annotation is the widened literal type of the initializer.
@@ -432,7 +396,6 @@ Where the widened type for a string literal type is `string`, `number` for numer
432
396
##### Example
433
397
434
398
```ts
435
-
436
399
const c1 =1; // Type 1
437
400
const c2 =c1; // Type 1
438
401
const c3 ="abc"; // Type "abc"
@@ -462,7 +425,7 @@ let v2 = c2; // Type "hello"
462
425
463
426
# Use returned values from super calls as 'this'
464
427
465
-
In ES2015, constructors which return a value (which is an object) implicitly substitute the value of `this` for any callers of `super()`.
428
+
In ES2015, constructors which return an object implicitly substitute the value of `this` for any callers of `super()`.
466
429
As a result, it is necessary to capture any potential return value of `super()` and replace it with `this`.
467
430
This change enables working with [Custom Elements](https://w3c.github.io/webcomponents/spec/custom/#htmlelement-constructor), which takes advantage of this to initialize browser-allocated elements with user-written constructors.
468
431
@@ -509,9 +472,9 @@ Just a few configuration options change between these two targets, and maintaini
509
472
TypeScript 2.1 supports inheriting configuration using `extends`, where:
510
473
511
474
*`extends` is a new top-level property in `tsconfig.json` (alongside `compilerOptions`, `files`, `include`, and `exclude`).
512
-
*`extends`' value is a string containing a path to another configuration file to inherit from.
475
+
*The value of `extends` must be a string containing a path to another configuration file to inherit from.
513
476
* The configuration from the base file are loaded first, then overridden by those in the inheriting config file.
514
-
*If a circularity is encountered, we report an error.
477
+
*Circularity between configuration files is not allowed.
515
478
*`files`, `include` and `exclude` from the inheriting config file *overwrite* those from the base config file.
516
479
* All relative paths found in the configuration file will be resolved relative to the configuration file they originated in.
517
480
@@ -560,13 +523,3 @@ Invoking the compiler with `--alwaysStrict` causes:
560
523
561
524
Modules are parsed automatically in strict mode.
562
525
The new flag is recommended for non-module code.
563
-
564
-
# Support for `--target ES2016`, `--target ES2017` and `--target ESNext`
565
-
566
-
TypeScript 2.1 supports three new target values `--target ES2016`, `--target ES2017` and `--target ESNext`.
567
-
568
-
Using target `--target ES2016` will instruct the compiler not to transform ES2016-specific features, e.g. `**` operator.
569
-
570
-
Similarly, `--target ES2017` will instruct the compiler not to transform ES2017-specific features like `async`/`await`.
0 commit comments