TypeScript 3.1

元组和数组上的映射类型

¥Mapped types on tuples and arrays

在 TypeScript 3.1 中,将对象类型 [1] 映射到元组和数组上现在会生成新的元组/数组,而不是创建一个新的类型,其中 push()pop()length 等成员会被转换。例如:

¥In TypeScript 3.1, mapped object types[1] over tuples and arrays now produce new tuples/arrays, rather than creating a new type where members like push(), pop(), and length are converted. For example:

ts
type MapToPromise<T> = { [K in keyof T]: Promise<T[K]> };
type Coordinate = [number, number];
type PromiseCoordinate = MapToPromise<Coordinate>; // [Promise<number>, Promise<number>]

MapToPromise 接受类型 T,当该类型为元组(例如 Coordinate)时,仅转换数字属性。在 [number, number] 中,有两个以数字命名的属性:01。当给定一个这样的元组时,MapToPromise 将创建一个新的元组,其中 01 属性是原始类型的 Promise。所以生成的类型 PromiseCoordinate 最终是类型 [Promise<number>, Promise<number>]

¥MapToPromise takes a type T, and when that type is a tuple like Coordinate, only the numeric properties are converted. In [number, number], there are two numerically named properties: 0 and 1. When given a tuple like that, MapToPromise will create a new tuple where the 0 and 1 properties are Promises of the original type. So the resulting type PromiseCoordinate ends up with the type [Promise<number>, Promise<number>].

函数上的属性声明

¥Properties declarations on functions

TypeScript 3.1 允许在函数声明和 const 声明的函数上定义属性,只需在同一作用域内对这些函数的属性进行赋值即可。这使我们能够编写规范的 JavaScript 代码,而无需诉诸 namespace 技巧。例如:

¥TypeScript 3.1 brings the ability to define properties on function declarations and const-declared functions, simply by assigning to properties on these functions in the same scope. This allows us to write canonical JavaScript code without resorting to namespace hacks. For example:

ts
function readImage(path: string, callback: (err: any, image: Image) => void) {
// ...
}
readImage.sync = (path: string) => {
const contents = fs.readFileSync(path);
return decodeImageSync(contents);
};

这里,我们有一个函数 readImage,它以非阻塞异步方式读取图片。除了 readImage 之外,我们还在 readImage 本身上提供了一个名为 readImage.sync 的便捷函数。

¥Here, we have a function readImage which reads an image in a non-blocking asynchronous way. In addition to readImage, we’ve provided a convenience function on readImage itself called readImage.sync.

虽然 ECMAScript 导出通常是提供此功能的更好方式,但这项新支持允许以这种风格编写的代码在 TypeScript 中导出为 “正常工作”。此外,这种属性声明方法使我们能够在 React 函数组件(以前称为 SFC)上表达像 defaultPropspropTypes 这样的常见模式。

¥While ECMAScript exports are often a better way of providing this functionality, this new support allows code written in this style to “just work” in TypeScript. Additionally, this approach for property declarations allows us to express common patterns like defaultProps and propTypes on React function components (formerly known as SFCs).

ts
export const FooComponent = ({ name }) => <div>Hello! I am {name}</div>;
FooComponent.defaultProps = {
name: "(anonymous)",
};

[1] 更具体地说,是像上面这样的同态映射类型。

¥[1] More specifically, homomorphic mapped types like in the above form.

typesVersions 的版本选择

¥Version selection with typesVersions

来自社区的反馈以及我们自身的经验表明,在充分利用最新的 TypeScript 功能的同时,还要兼顾旧版本的用户非常困难。TypeScript 引入了一项名为 typesVersions 的新功能来帮助适应这些场景。

¥Feedback from our community, as well as our own experience, has shown us that leveraging the newest TypeScript features while also accommodating users on the older versions are difficult. TypeScript introduces a new feature called typesVersions to help accommodate these scenarios.

你可以读取 详情请参阅声明文件部分的“发布”部分

¥You can read about it in the Publishing section of the declaration files section