TypeScript 3.1
元组和数组上的映射类型
在 TypeScript 3.1 中,元组和数组上的映射对象类型[1]现在会生成新的元组/数组,而不是创建一个将 push()、pop() 和 length 等成员都转换掉的新类型。例如:
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] 中,有两个数字命名的属性:0 和 1。当给定这样一个元组时,MapToPromise 将创建一个新元组,其中 0 和 1 属性是原始类型的 Promise。因此,结果类型 PromiseCoordinate 最终得到类型 [Promise<number>, Promise<number>]。
函数上的属性声明
TypeScript 3.1 带来了在函数声明和 const 声明的函数上定义属性的能力,只需在同一作用域中向这些函数的属性赋值即可。这使我们能够编写规范的 JavaScript 代码,而无需借助 namespace 的技巧。例如:
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。
虽然 ECMAScript 导出通常是提供此功能的更好方式,但这种新支持允许以这种风格编写的代码在 TypeScript 中“正常工作”。此外,这种属性声明方法使我们能够在 React 函数组件(以前称为 SFC)上表达常见模式,如 defaultProps 和 propTypes。
export const FooComponent = ({ name }) => <div>Hello! I am {name}</div>;
FooComponent.defaultProps = {
name: "(anonymous)",
};[1] 更具体地说,是上述形式的同态映射类型。
使用 typesVersions 进行版本选择
来自社区的反馈以及我们自身的经验表明,在利用最新 TypeScript 功能的同时还要兼容旧版本的用户是很困难的。TypeScript 引入了一个名为 typesVersions 的新功能来帮助应对这些场景。