Merge pull request #262 from FanShikun/master
Breaking changes for TypeScript 2.9, 3.0, 3.2, 3.4, 3.5
This commit is contained in:
commit
c920f6542c
@ -102,7 +102,12 @@
|
||||
* [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.5](./doc/breaking-changes/TypeScript%203.5.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)
|
||||
* [TypeScript 2.9](./doc/breaking-changes/TypeScript%202.9.md)
|
||||
* [TypeScript 2.8](./doc/breaking-changes/TypeScript%202.8.md)
|
||||
* [TypeScript 2.7](./doc/breaking-changes/TypeScript%202.7.md)
|
||||
* [TypeScript 2.6](./doc/breaking-changes/TypeScript%202.6.md)
|
||||
|
@ -86,7 +86,12 @@
|
||||
* [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.5](./doc/breaking-changes/TypeScript 3.5.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)
|
||||
* [TypeScript 2.9](./doc/breaking-changes/TypeScript 2.9.md)
|
||||
* [TypeScript 2.8](./doc/breaking-changes/TypeScript 2.8.md)
|
||||
* [TypeScript 2.7](./doc/breaking-changes/TypeScript 2.7.md)
|
||||
* [TypeScript 2.6](./doc/breaking-changes/TypeScript 2.6.md)
|
||||
|
60
doc/breaking-changes/TypeScript 2.9.md
Normal file
60
doc/breaking-changes/TypeScript 2.9.md
Normal file
@ -0,0 +1,60 @@
|
||||
# TypeScript 2.9
|
||||
|
||||
## `keyof` 现在包括 `string`、`number` 和 `symbol` 键名
|
||||
|
||||
TypeScript 2.9 将索引类型泛化为包括 `number` 和 `symbol` 命名属性。以前,`keyof` 运算符和映射类型仅支持 `string` 命名属性。
|
||||
|
||||
```ts
|
||||
function useKey<T, K extends keyof T>(o: T, k: K) {
|
||||
var name: string = k; // 错误: keyof T 不能分配给 `string`
|
||||
}
|
||||
```
|
||||
|
||||
### 建议
|
||||
|
||||
* 如果你的函数只能处理名字符串属性的键,请在声明中使用 `Extract<keyof T,string>`:
|
||||
|
||||
```ts
|
||||
function useKey<T, K extends Extract<keyof T, string>>(o: T, k: K) {
|
||||
var name: string = k; // OK
|
||||
}
|
||||
```
|
||||
|
||||
* 如果你的函数可以处理所有属性键,那么更改应该是顺畅的:
|
||||
|
||||
```ts
|
||||
function useKey<T, K extends keyof T>(o: T, k: K) {
|
||||
var name: string | number | symbol = k;
|
||||
}
|
||||
```
|
||||
|
||||
* 除此之外,还可以使用 `--keyofStringsOnly` 编译器选项禁用新行为。
|
||||
|
||||
## 剩余参数后面不允许尾后逗号
|
||||
|
||||
以下代码是一个自 [#22262](https://github.com/Microsoft/TypeScript/pull/22262) 开始的编译器错误:
|
||||
|
||||
```ts
|
||||
function f(
|
||||
a: number,
|
||||
...b: number[], // 违规的尾随逗号
|
||||
) {}
|
||||
```
|
||||
|
||||
剩余参数上的尾随逗号不是有效的 JavaScript,并且,这个语法现在在 TypeScript 中也是一个错误。
|
||||
|
||||
## 在 `strictNullChecks` 中,无类型约束参数不再分配给 `object`
|
||||
|
||||
以下代码是自[24013](https://github.com/microsoft/typescript/issues/24013)起在 `strickNullChecks` 下出现的编译器错误:
|
||||
|
||||
```ts
|
||||
function f<T>(x: T) {
|
||||
const y: object | null | undefined = x;
|
||||
}
|
||||
```
|
||||
|
||||
它可以用任意类型(例如,`string` 或 `number` )来实现,因此允许它是不正确的。 如果您遇到此问题,请将您的类型参数约束为 `object` 以仅允许对象类型。如果想允许任何类型,使用 `{}` 进行比较而不是 `object`。
|
||||
|
||||
## 参考
|
||||
|
||||
* [原文](https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#typescript-29)
|
24
doc/breaking-changes/TypeScript 3.0.md
Normal file
24
doc/breaking-changes/TypeScript 3.0.md
Normal file
@ -0,0 +1,24 @@
|
||||
# TypeScript 3.0
|
||||
|
||||
## 保留关键字 `unknown`
|
||||
|
||||
`unknown` 现在是一个保留类型名称,因为它现在是一个内置类型。为了支持新引入的 `unknown` 类型,取决于你对 `unknown` 的使用方式,你可能需要完全移除变量申明,或者将其重命名。
|
||||
|
||||
## 未开启 `strictNullChecks` 时,与 `null`/`undefined` 交叉的类型会简化到 `null`/`undefined`
|
||||
|
||||
关闭 `strictNullChecks` 时,下例中 `A` 的类型为 `null`,而 `B` 的类型为 `undefined`:
|
||||
|
||||
```ts
|
||||
type A = { a: number } & null; // null
|
||||
type B = { a: number } & undefined; // undefined
|
||||
```
|
||||
|
||||
这是因为 TypeScript 3.0 更适合分别简化交叉类型和联合类型中的子类型和超类型。但是,因为当 `strictNullChecks` 关闭时,`null` 和 `undefined` 都被认为是所有其他类型的子类型,与某种对象类型的交集将始终简化为 `null` 或 `undefined`。
|
||||
|
||||
### 建议
|
||||
|
||||
如果你在类型交叉的情况下依赖 `null` 和 `undefined` 作为[单位元](https://baike.baidu.com/item/%E5%8D%95%E4%BD%8D%E5%85%83),你应该寻找一种方法来使用 `unknown` 而不是无论它们在哪里都是 `null` 或 `undefined`。
|
||||
|
||||
## 参考
|
||||
|
||||
* [原文](https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#typescript-30)
|
17
doc/breaking-changes/TypeScript 3.2.md
Normal file
17
doc/breaking-changes/TypeScript 3.2.md
Normal file
@ -0,0 +1,17 @@
|
||||
# TypeScript 3.2
|
||||
|
||||
## `lib.d.ts` 更新
|
||||
|
||||
### `wheelDelta` 和它的小伙伴们被移除了。
|
||||
|
||||
`wheelDeltaX`、`wheelDelta` 和 `wheelDeltaZ` 全都被移除了,因为他们在 `WheelEvent`s 上是废弃的属性。
|
||||
|
||||
**解决办法**:使用 `deltaX`、`deltaY` 和 `deltaZ` 代替。
|
||||
|
||||
### 更具体的类型
|
||||
|
||||
根据 DOM 规范的描述,某些参数现在接受更具体的类型,不再接受 `null`。
|
||||
|
||||
## 参考
|
||||
|
||||
* [原文](https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#typescript-32)
|
114
doc/breaking-changes/TypeScript 3.4.md
Normal file
114
doc/breaking-changes/TypeScript 3.4.md
Normal file
@ -0,0 +1,114 @@
|
||||
# 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` 获取不合需要的字面量类型。
|
||||
|
||||
```sh
|
||||
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)
|
16
doc/breaking-changes/TypeScript 3.5.md
Normal file
16
doc/breaking-changes/TypeScript 3.5.md
Normal file
@ -0,0 +1,16 @@
|
||||
# TypeScript 3.5
|
||||
|
||||
## `lib.d.ts` 包含了 `Omit` 辅助类型
|
||||
|
||||
TypeScript 3.5 包含一个 `Omit` 辅助类型。
|
||||
|
||||
因此, 你项目中任何全局定义的 `Omit` 将产生以下错误信息:
|
||||
|
||||
```ts
|
||||
Duplicate identifier 'Omit'.
|
||||
```
|
||||
|
||||
两个变通的方法可以在这里使用:
|
||||
|
||||
1. 删除重复定义的并使用 `lib.d.ts` 提供的。
|
||||
2. 从模块中导出定义避免全局冲突。现有的用法可以使用 `import` 直接引用项目的旧 `Omit` 类型。
|
@ -1,7 +1,12 @@
|
||||
# Breaking Changes
|
||||
|
||||
* [TypeScript 3.6](./TypeScript 3.6.md)
|
||||
* [TypeScript 3.5](./TypeScript 3.5.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)
|
||||
* [TypeScript 2.9](./TypeScript 2.9.md)
|
||||
* [TypeScript 2.8](./TypeScript 2.8.md)
|
||||
* [TypeScript 2.7](./TypeScript 2.7.md)
|
||||
* [TypeScript 2.6](./TypeScript 2.6.md)
|
||||
|
@ -69,7 +69,7 @@ function compose<A, B, C>(f: (arg: A) => B, g: (arg: B) => C): (arg: A) => C {
|
||||
`compose` 然后返回一个函数,它通过 `f` 然后 `g` 来提供它的参数。
|
||||
|
||||
调用此函数时,TypeScript 将尝试通过一个名为 *type argument inference* 的进程来计算出 `A`,`B` 和 `C` 的类型。
|
||||
这个推理过程通常很有效:
|
||||
这个推断过程通常很有效:
|
||||
|
||||
```ts
|
||||
interface Person {
|
||||
@ -95,7 +95,7 @@ const getDisplayNameLength = compose(
|
||||
getDisplayNameLength({ name: "Person McPersonface", age: 42 });
|
||||
```
|
||||
|
||||
推理过程在这里相当简单,因为 `getDisplayName` 和 `getLength` 使用的是可以轻松引用的类型。
|
||||
推断过程在这里相当简单,因为 `getDisplayName` 和 `getLength` 使用的是可以轻松引用的类型。
|
||||
但是,在 TypeScript 3.3 及更早版本中,泛型函数如 `compose` 在传递其他泛型函数时效果不佳。
|
||||
|
||||
```ts
|
||||
|
Loading…
Reference in New Issue
Block a user