Breaking changes for TypeScript 3.4

This commit is contained in:
ShikunFan 2019-09-14 14:25:00 +08:00
parent ed4a900655
commit c26ce88abc
4 changed files with 116 additions and 0 deletions

View File

@ -102,6 +102,7 @@
* [TypeScript 1.1](./doc/release-notes/TypeScript%201.1.md)
* [Breaking Changes](./doc/breaking-changes/breaking-changes.md)
* [TypeScript 3.6](./doc/breaking-changes/TypeScript%203.6.md)
* [TypeScript 3.4](./doc/breaking-changes/TypeScript%203.4.md)
* [TypeScript 3.2](./doc/breaking-changes/TypeScript%203.2.md)
* [TypeScript 3.1](./doc/breaking-changes/TypeScript%203.1.md)
* [TypeScript 3.0](./doc/breaking-changes/TypeScript%203.0.md)

View File

@ -86,6 +86,7 @@
* [TypeScript 1.1](./doc/release-notes/TypeScript 1.1.md)
* [Breaking Changes](./doc/breaking-changes/breaking-changes.md)
* [TypeScript 3.6](./doc/breaking-changes/TypeScript 3.6.md)
* [TypeScript 3.4](./doc/breaking-changes/TypeScript 3.4.md)
* [TypeScript 3.2](./doc/breaking-changes/TypeScript 3.2.md)
* [TypeScript 3.1](./doc/breaking-changes/TypeScript 3.1.md)
* [TypeScript 3.0](./doc/breaking-changes/TypeScript 3.0.md)

View File

@ -0,0 +1,113 @@
# TypeScript 3.4
## 顶级 `this` 现在有类型了
顶级 `this` 的类型现在被分配为 `typeof globalThis` 而不是 `any`
因此, 在 `noImplicitAny` 下访问 `this` 上的未知值,你可能收到错误提示。
```ts
// 在 `noImplicitAny` 下,以前可以,现在不行
this.whargarbl = 10;
```
请注意,在 `noImplicitThis` 下编译的代码不会在此处遇到任何更改。
## 泛型参数的传递
在某些情况下TypeScript 3.4 的推断改进可能会产生泛型的函数,而不是那些接收并返回其约束的函数(通常是 `{}`)。
```ts
declare function compose<T, U, V>(f: (arg: T) => U, g: (arg: U) => V): (arg: T) => V;
function list<T>(x: T) { return [x]; }
function box<T>(value: T) { return { value }; }
let f = compose(list, box);
let x = f(100)
// 在 TypeScript 3.4 中, 'x.value' 的类型为
//
// number[]
//
// 但是在之前的版本中类型为
//
// {}[]
//
// 因此,插入一个 `string` 类型是错误的
x.value.push("hello");
```
`x` 上的显式类型注释可以清除这个错误。
### 上下文返回类型作为上下文参数类型传入
TypeScript 现在使用函数调用时传入的类型(如下例中的 `then`)作为函数上下文参数类型(如下例中的箭头函数)。
```ts
function isEven(prom: Promise<number>): Promise<{ success: boolean }> {
return prom.then<{success: boolean}>((x) => {
return x % 2 === 0 ?
{ success: true } :
Promise.resolve({ success: false });
});
}
```
这通常是一种改进,但在上面的例子中,它导致 `true``false` 获取不合需要的字面量类型。
```
Argument of type '(x: number) => Promise<{ success: false; }> | { success: true; }' is not assignable to parameter of type '(value: number) => { success: false; } | PromiseLike<{ success: false; }>'.
Type 'Promise<{ success: false; }> | { success: true; }' is not assignable to type '{ success: false; } | PromiseLike<{ success: false; }>'.
Type '{ success: true; }' is not assignable to type '{ success: false; } | PromiseLike<{ success: false; }>'.
Type '{ success: true; }' is not assignable to type '{ success: false; }'.
Types of property 'success' are incompatible.
```
合适的解决方法是将类型参数添加到适当的调用——本例中的 `then` 方法调用。
```ts
function isEven(prom: Promise<number>): Promise<{ success: boolean }> {
// vvvvvvvvvvvvvvvvvv
return prom.then<{success: boolean}>((x) => {
return x % 2 === 0 ?
{ success: true } :
Promise.resolve({ success: false });
});
}
```
### 在 `strictFunctionTypes` 之外一致性推断优先
在 TypeScript 3.3 中,关闭 `--strictFunctionTypes` 选项时,假定使用 `interface` 声明的泛型类型在其类型参数方面始终是协变的。对于函数类型,通常无法观察到此行为。
但是,对于带有 `keyof` 状态的类型参数的泛型 `interface` 类型——逆变用法——这些类型表现不正确。
在 TypeScript 3.4 中,现在可以在所有情况下正确探测使用 `interface` 声明的类型的变动。
这导致一个可见的重大变更,只要有类型参数的接口使用了 `keyof`(包括诸如 `Record<K, T>` 之类的地方,这是涉及 `keyof K` 的类型别名)。下例就是这样一个可能的变更。
```ts
interface HasX { x: any }
interface HasY { y: any }
declare const source: HasX | HasY;
declare const properties: KeyContainer<HasX>;
interface KeyContainer<T> {
key: keyof T;
}
function readKey<T>(source: T, prop: KeyContainer<T>) {
console.log(source[prop.key])
}
// 这个调用应该被拒绝,因为我们可能会这样做
// 错误地从 'HasY' 中读取 'x'。它现在恰当的提示错误。
readKey(source, properties);
```
此错误很可能表明原代码存在问题。
## 参考
* [原文](https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#typescript-34)

View File

@ -1,6 +1,7 @@
# Breaking Changes
* [TypeScript 3.6](./TypeScript 3.6.md)
* [TypeScript 3.4](./TypeScript 3.4.md)
* [TypeScript 3.2](./TypeScript 3.2.md)
* [TypeScript 3.1](./TypeScript 3.1.md)
* [TypeScript 3.0](./TypeScript 3.0.md)