Skip to content

Commit efb5cce

Browse files
authored
Merge branch 'master' into patch-1
2 parents afc8bd9 + 1593ca2 commit efb5cce

File tree

9 files changed

+177
-11
lines changed

9 files changed

+177
-11
lines changed

pages/Advanced Types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ Note that `Readonly<T>` and `Partial<T>` are so useful, they are included in Typ
863863
type Pick<T, K extends keyof T> = {
864864
[P in K]: T[P];
865865
}
866-
type Record<K extends string | number, T> = {
866+
type Record<K extends string, T> = {
867867
[P in K]: T;
868868
}
869869
```

pages/Compiler Options.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Option | Type | Default
3333
`--locale` | `string` | *(platform specific)* | The locale to use to show error messages, e.g. en-us.
3434
`--mapRoot` | `string` | | Specifies the location where debugger should locate map files instead of generated locations. Use this flag if the .map files will be located at run-time in a different location than the .js files. The location specified will be embedded in the sourceMap to direct the debugger where the map files will be located.
3535
`--maxNodeModuleJsDepth` | `number` | `0` | The maximum dependency depth to search under node_modules and load JavaScript files. Only applicable with `--allowJs`.
36-
`--module`<br/>`-m` | `string` | `target === "ES6" ? "ES6" : "CommonJS"` | Specify module code generation: `"None"`, `"CommonJS"`, `"AMD"`, `"System"`, `"UMD"`, `"ES6"`, or `"ES2015"`.<br/>► Only `"AMD"` and `"System"` can be used in conjunction with `--outFile`.<br/>► `"ES6"` and `"ES2015"` values may be used when targeting `"ES5"` or lower.
36+
`--module`<br/>`-m` | `string` | `target === "ES6" ? "ES6" : "CommonJS"` | Specify module code generation: `"None"`, `"CommonJS"`, `"AMD"`, `"System"`, `"UMD"`, `"ES6"`, `"ES2015"` or `"ESNext"`.<br/>► Only `"AMD"` and `"System"` can be used in conjunction with `--outFile`.<br/>► `"ES6"` and `"ES2015"` values may be used when targeting `"ES5"` or lower.
3737
`--moduleResolution` | `string` | `module === "AMD" | "System" | "ES6" ? "Classic" : "Node"` | Determine how modules get resolved. Either `"Node"` for Node.js/io.js style resolution, or `"Classic"`. See [Module Resolution documentation](./Module Resolution.md) for more details.
3838
`--newLine` | `string` | *(platform specific)* | Use the specified end of line sequence to be used when emitting files: `"crlf"` (windows) or `"lf"` (unix)."
3939
`--noEmit` | `boolean` | `false` | Do not emit outputs.
@@ -46,6 +46,7 @@ Option | Type | Default
4646
`--noImplicitUseStrict` | `boolean` | `false` | Do not emit `"use strict"` directives in module output.
4747
`--noLib` | `boolean` | `false` | Do not include the default library file (`lib.d.ts`).
4848
`--noResolve` | `boolean` | `false` | Do not add triple-slash references or module import targets to the list of compiled files.
49+
`--noStrictGenericChecks` | `boolean` | `false` | Disable strict checking of generic signatures in function types.
4950
`--noUnusedLocals` | `boolean` | `false` | Report errors on unused locals.
5051
`--noUnusedParameters` | `boolean` | `false` | Report errors on unused parameters.
5152
~~`--out`~~ | `string` | | DEPRECATED. Use `--outFile` instead.

pages/Functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ TypeScript can figure the return type out by looking at the return statements, s
5656
Now that we've typed the function, let's write the full type of the function out by looking at the each piece of the function type.
5757

5858
```ts
59-
let myAdd: (x: number, y: number)=>number =
59+
let myAdd: (x: number, y: number) => number =
6060
function(x: number, y: number): number { return x+y; };
6161
```
6262

pages/JSX.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ An intrinsic element always begins with a lowercase letter, and a value-based el
6666

6767
Intrinsic elements are looked up on the special interface `JSX.IntrinsicElements`.
6868
By default, if this interface is not specified, then anything goes and intrinsic elements will not be type checked.
69-
However, if interface *is* present, then the name of the intrinsic element is looked up as a property on the `JSX.IntrinsicElements` interface.
69+
However, if this interface *is* present, then the name of the intrinsic element is looked up as a property on the `JSX.IntrinsicElements` interface.
7070
For example:
7171

7272
```ts

pages/Module Resolution.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ You can find more documentation on baseUrl in [RequireJS](http://requirejs.org/d
204204
### Path mapping
205205

206206
Sometimes modules are not directly located under *baseUrl*.
207-
For instance, an import to a module `"jquery"` would be translated at runtime to `"node_modules\jquery\dist\jquery.slim.min.js"`.
207+
For instance, an import to a module `"jquery"` would be translated at runtime to `"node_modules/jquery/dist/jquery.slim.min.js"`.
208208
Loaders use a mapping configuration to map module names to files at run-time, see [RequireJs documentation](http://requirejs.org/docs/api.html#config-paths) and [SystemJS documentation](https://github.com/systemjs/systemjs/blob/master/docs/config-api.md#paths).
209209

210210
The TypeScript compiler supports the declaration of such mappings using `"paths"` property in `tsconfig.json` files.
@@ -260,8 +260,8 @@ The corresponding `tsconfig.json` would look like:
260260

261261
This tells the compiler for any module import that matches the pattern `"*"` (i.e. all values), to look in two locations:
262262

263-
1. `"*"`: meaning the same name unchanged, so map `<moduleName>` => `<baseUrl>\<moduleName>`
264-
2. `"generated\*"` meaning the module name with an appended prefix "generated", so map `<moduleName>` => `<baseUrl>\generated\<moduleName>`
263+
1. `"*"`: meaning the same name unchanged, so map `<moduleName>` => `<baseUrl>/<moduleName>`
264+
2. `"generated/*"` meaning the module name with an appended prefix "generated", so map `<moduleName>` => `<baseUrl>/generated/<moduleName>`
265265

266266
Following this logic, the compiler will attempt to resolve the two imports as such:
267267

pages/Modules.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ It's important to note that in TypeScript 1.5, the nomenclature has changed.
55

66
# Introduction
77

8-
Starting with the ECMAScript 2015, JavaScript has a concept of modules. TypeScript shares this concept.
8+
Starting with ECMAScript 2015, JavaScript has a concept of modules. TypeScript shares this concept.
99

1010
Modules are executed within their own scope, not in the global scope; this means that variables, functions, classes, etc. declared in a module are not visible outside the module unless they are explicitly exported using one of the [`export` forms](#export).
1111
Conversely, to consume a variable, function, class, interface, etc. exported from a different module, it has to be imported using one of the [`import` forms](#import).
@@ -581,7 +581,7 @@ Consumers of your module should have as little friction as possible when using t
581581
Adding too many levels of nesting tends to be cumbersome, so think carefully about how you want to structure things.
582582

583583
Exporting a namespace from your module is an example of adding too many layers of nesting.
584-
While namespaces sometimes have their uses, they add an extra level of indirection when using modules.
584+
While namespaces sometime have their uses, they add an extra level of indirection when using modules.
585585
This can quickly becomes a pain point for users, and is usually unnecessary.
586586

587587
Static methods on an exported class have a similar problem - the class itself adds a layer of nesting.

pages/declaration files/Do's and Don'ts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Note that this collapsing should only occur when all overloads have the same ret
162162
*Why*: This is important for two reasons.
163163

164164
TypeScript resolves signature compatibility by seeing if any signature of the target can be invoked with the arguments of the source,
165-
*and extraneuous arguments are allowed*.
165+
*and extraneous arguments are allowed*.
166166
This code, for example, exposes a bug only when the signature is correctly written using optional parameters:
167167

168168
```ts

pages/release notes/TypeScript 2.3.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ A generic parameter default follows the following rules:
132132
* Required type parameters must not follow optional type parameters.
133133
* Default types for a type parameter must satisfy the constraint for the type parameter, if it exists.
134134
* When specifying type arguments, you are only required to specify type arguments for the required type parameters. Unspecified type parameters will resolve to their default types.
135-
* If a default type is specified and inference cannot chose a candidate, the default type is inferred.
135+
* If a default type is specified and inference cannot choose a candidate, the default type is inferred.
136136
* A class or interface declaration that merges with an existing class or interface declaration may introduce a default for an existing type parameter.
137137
* A class or interface declaration that merges with an existing class or interface declaration may introduce a new type parameter as long as it specifies a default.
138138

pages/release notes/TypeScript 2.4.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# TypeScript 2.4
2+
3+
## Dynamic Import Expressions
4+
5+
Dynamic `import` expressions are a new feature and part of ECMAScript that allows users to asynchronously request a module at any arbitrary point in your program.
6+
7+
This means that you can conditionally and lazily import other modules and libraries.
8+
For example, here's an `async` function that only imports a utility library when it's needed:
9+
10+
```ts
11+
async function getZipFile(name: string, files: File[]): Promise<File> {
12+
const zipUtil = await import('./utils/create-zip-file');
13+
const zipContents = await zipUtil.getContentAsBlob(files);
14+
return new File(zipContents, name);
15+
}
16+
```
17+
18+
Many bundlers have support for automatically splitting output bundles based on these `import` expressions, so consider using this new feature with the `esnext` module target.
19+
20+
## String Enums
21+
22+
TypeScript 2.4 now allows enum members to contain string initializers.
23+
24+
```ts
25+
enum Colors {
26+
Red = "RED",
27+
Green = "GREEN",
28+
Blue = "BLUE",
29+
}
30+
```
31+
32+
The caveat is that string-initialized enums can't be reverse-mapped to get the original enum member name.
33+
In other words, you can't write `Colors["RED"]` to get the string `"Red"`.
34+
35+
## Improved inference for generics
36+
37+
TypeScript 2.4 introduces a few wonderful changes around the way generics are inferred.
38+
39+
### Return types as inference targets
40+
41+
For one, TypeScript can now make inferences for the return type of a call.
42+
This can improve your experience and catch errors.
43+
Something that now works:
44+
45+
```ts
46+
function arrayMap<T, U>(f: (x: T) => U): (a: T[]) => U[] {
47+
return a => a.map(f);
48+
}
49+
50+
const lengths: (a: string[]) => number[] = arrayMap(s => s.length);
51+
```
52+
53+
As an example of new errors you might spot as a result:
54+
55+
```ts
56+
let x: Promise<string> = new Promise(resolve => {
57+
resolve(10);
58+
// ~~ Error!
59+
});
60+
```
61+
62+
### Type parameter inference from contextual types
63+
64+
Prior to TypeScript 2.4, in the following example
65+
66+
```ts
67+
let f: <T>(x: T) => T = y => y;
68+
```
69+
70+
`y` would have the type `any`.
71+
This meant the program would type-check, but you could technically do anything with `y`, such as the following:
72+
73+
```ts
74+
let f: <T>(x: T) => T = y => y() + y.foo.bar;
75+
```
76+
77+
That last example isn't actually type-safe.
78+
79+
In TypeScript 2.4, the function on the right side implicitly *gains* type parameters, and `y` is inferred to have the type of that type-parameter.
80+
81+
If you use `y` in a way that the type parameter's constraint doesn't support, you'll correctly get an error.
82+
In this case, the constraint of `T` was (implicitly) `{}`, so the last example will appropriately fail.
83+
84+
### Stricter checking for generic functions
85+
86+
TypeScript now tries to unify type parameters when comparing two single-signature types.
87+
As a result, you'll get stricter checks when relating two generic signatures, and may catch some bugs.
88+
89+
```ts
90+
type A = <T, U>(x: T, y: U) => [T, U];
91+
type B = <S>(x: S, y: S) => [S, S];
92+
93+
function f(a: A, b: B) {
94+
a = b; // Error
95+
b = a; // Ok
96+
}
97+
```
98+
99+
## Strict contravariance for callback parameters
100+
101+
TypeScript has always compared parameters in a bivariant way.
102+
There are a number of reasons for this, but by-and-large this was not been a huge issue for our users until we saw some of the adverse effects it had with `Promise`s and `Observable`s.
103+
104+
TypeScript 2.4 introduces tightens this up when relating two callback types. For example:
105+
106+
```ts
107+
interface Mappable<T> {
108+
map<U>(f: (x: T) => U): Mappable<U>;
109+
}
110+
111+
declare let a: Mappable<number>;
112+
declare let b: Mappable<string | number>;
113+
114+
a = b;
115+
b = a;
116+
```
117+
118+
Prior to TypeScript 2.4, this example would succeed.
119+
When relating the types of `map`, TypeScript would bidirectionally relate their parameters (i.e. the type of `f`).
120+
When relating each `f`, TypeScript would also bidirectionally relate the type of *those* parameters.
121+
122+
When relating the type of `map` in TS 2.4, the language will check whether each parameter is a callback type, and if so, it will ensure that those parameters are checked in a contravariant manner with respect to the current relation.
123+
124+
In other words, TypeScript now catches the above bug, which may be a breaking change for some users, but will largely be helpful.
125+
126+
## Weak Type Detection
127+
128+
TypeScript 2.4 introduces the concept of "weak types".
129+
Any type that contains nothing but a set of all-optional properties is considered to be *weak*.
130+
For example, this `Options` type is a weak type:
131+
132+
```ts
133+
interface Options {
134+
data?: string,
135+
timeout?: number,
136+
maxRetries?: number,
137+
}
138+
```
139+
140+
In TypeScript 2.4, it's now an error to assign anything to a weak type when there's no overlap in properties.
141+
For example:
142+
143+
```ts
144+
function sendMessage(options: Options) {
145+
// ...
146+
}
147+
148+
const opts = {
149+
payload: "hello world!",
150+
retryOnFail: true,
151+
}
152+
153+
// Error!
154+
sendMessage(opts);
155+
// No overlap between the type of 'opts' and 'Options' itself.
156+
// Maybe we meant to use 'data'/'maxRetries' instead of 'payload'/'retryOnFail'.
157+
```
158+
159+
You can think of this as TypeScript "toughening up" the weak guarantees of these types to catch what would otherwise be silent bugs.
160+
161+
Since this is a breaking change, you may need to know about the workarounds which are the same as those for strict object literal checks:
162+
163+
1. Declare the properties if they really do exist.
164+
2. Add an index signature to the weak type (i.e. `[propName: string]: {}`).
165+
3. Use a type assertion (i.e. `opts as Options`).

0 commit comments

Comments
 (0)