TypeScript 3.9 版本带来了多项关键改进,重点修复了 Promise.all 在处理 null 和 undefined 时的类型定义问题,并大幅提升了编译打包速度。此外,该版本引入了对三元运算符中未调用函数检测的支持,优化了编辑器对 CommonJS 模块的自动导入功能,并修正了可选链与非空断言结合使用的行为。
TypeScript 3.9 更新概况
更新了什么?概况一览
1、优化了 Promise.all 的定义,在 3.7 版本中一些混用 null 或 undefined 的时候的问题已经在 3.9 得到了修复。 2、大大的提高了打包速度,微软团队自测的时候 typescript项目的平均编译时间由 26s 缩短到了 10s 左右。 3、// @ts-expect-error 新注释的添加 4、在条件语句中检测未调用的函数 5、编辑器提升
- 5.1 在 JavaScript 中自动引入 CommonJS 模块
- 5.2 在代码操作过程中正确保留换行符
- 5.3 添加快速修复缺失的函数返回表达式
- 5.4 支持 "Solution Style" 模式的 tsconfig.json 文件
6、一些重大变化
主要涉及 TypeScript 定义和书写规范的调整,以及既往 bug 的修复。
以下选取几个重点进行详细说明。
Promise.all 类型修复与 awaited type
1、interface 的优化以及 Promise.all 使用的修复
我们知道在 3.7 版本后,Promise.all 和 Promise.race 等方法进行了更新,但这同时也引发了一些问题,尤其是在处理 null 和 undefined 时表现尤为明显。
nterface Lion {
roar(): void
}
interface Seal {
singKissFromARose(): void
}
async function visitZoo(lionExhibit: Promise<Lion>, sealExhibit: Promise<Seal | undefined>) {
let [lion, seal] = await Promise.all([lionExhibit, sealExhibit]);
lion.roar(); // uh oh
// ~~~~
// Object is possibly 'undefined'.
}
这种行为显得较为奇怪,实际上 sealExhibit 中包含的 undefined 相当于将 undefined 错误地引入到了 lion type 中,这属于一个错误引用。
当然,在最新的 3.9 版本中,这个问题已经得到了修复。
1.1 全新的 awaited type
awaited type 主要是为了对现有的 Promise 进行更精准的定义和使用。
该特性预计在 **`3.9`** 版本发布,但微软再次延期,可以等待下一个版本。
编译与打包性能优化
2、TypeScript 打包编译等速度提升
这里主要优化了几个微软内部项目的性能,例如:
- Typescript 团队发现以前的 Material-ui 与 Styled-Components 等组件会带来极差的编辑 / 编译速度后。主要从联合类型、交叉类型、条件 判断的 type 类型以及各种映射 type 类型的性能问题来优化。 把相关的库编译时间减少了 40% 左右。
- 根据 Visual Studio Code 团队提供的建议,我们发现在执行文件重命名时,单是查明哪些导入语句需要更新就要耗去 5 到 10 秒时间。TypeScript 3.9 调整了内部编译器与语言服务缓存文件的查找方式,顺利解决了这个问题。
详情可以看看下面这几个 pull request 的具体优化内容
https://github.com/microsoft/TypeScript/pull/36576 https://github.com/microsoft/TypeScript/pull/36590 https://github.com/microsoft/TypeScript/pull/36607 https://github.com/microsoft/TypeScript/pull/36622 https://github.com/microsoft/TypeScript/pull/36754 https://github.com/microsoft/TypeScript/pull/36696
条件语句中的函数调用检测
4、在条件语句中检测未调用的函数
在 3.7 的时候引入了检测未调用函数错误提示,3.9 做了部分优化
function hasImportantPermissions(): boolean {
// ...
}
// Oops!
if (hasImportantPermissions) {
// ~~~~~~~~~~~~~~~~~~~~~~~
// This condition will always return true since the function is always defined.
// Did you mean to call it instead?
deleteAllTheImportantFiles();
}
但是,此错误仅适用于if语句中的条件。现在三元条件(即语法)现在也支持此功能。比如 cond ? trueExpr : falseExpr
declare function listFilesOfDirectory(dirPath: string): string[];
declare function isDirectory(): boolean;
function getAllFiles(startFileName: string) {
const result: string[] = [];
traverse(startFileName);
return result;
function traverse(currentPath: string) {
return isDirectory ?
// ~~~~~~~~~~~
// This condition will always return true
// since the function is always defined.
// Did you mean to call it instead?
listFilesOfDirectory(currentPath).forEach(traverse) :
result.push(currentPath);
}
}
编辑器功能增强:CommonJS 与自动修复
5、编辑器的提升
5.1 CommonJS 的自动补全
新版本的另一项重大改进,是使用 CommonJS 模块自动导入 JavaScript 文件。 在旧版本中,TypeScript 强制要求用户无论使用什么文件,都必须以 ECMAScript 的形式导入,例如:
import * as fs from "fs";
但在编写 JavaScript 文件时,很多用户并不打算使用 ECMScript 样式模块。不少朋友仍在使用 CommonJS 样式的 require(...) 导入,例如:
const fs = require("fs");
TypeScript 现在能够自动检测您所使用的导入类型,保证文件样式简洁而统一。现在有了如下自动引入的功能
const { readFile } = require('fs')
5.2 缺失的函数返回值的自动修复功能
在某些情况下,我们可能会忘记返回函数中的最后一条语句的值,尤其是在向箭头函数添加大括号时。
// before
let f1 = () => 42
// oops - not the same!
let f2 = () => { 42 }
可选链与非空断言的行为修正
6、重大改进!
6.1 解析可选链与非 null 断言中的差异
ypeScript 最近实现了对可选链操作符的支持,但根据广大使用者的反馈,非 null 断言操作符(!)的可选链(?.)行为不符合直觉。
具体来讲,在以往的版本中,代码:
foo?.bar!.baz
被解释为等效于以下 JavaScript 代码:
(foo?.bar).baz
在以上代码中,括号会阻止可选链的“短路”行为;因此如果未定义 foo 为 undefined,则访问 baz 会引发运行时错误。
换句话说,大多数人认为以上原始代码片段应该被解释为在:
foo?.bar.baz
中,当 foo 为 undefined 时,计算结果为 undefined。
这是一项重大变化,但我们认为大部分代码在编写时都是为了考虑新的解释场景。如果您希望继续使用旧有行为,则可在!操作符左侧添加括号,如下所示:
(foo?.bar)!.baz
参考
https://www.typescriptlang.org/docs/home.html
到此这篇关于Typescript3.9 常用新特性一览(推荐)的文章就介绍到这了,更多相关Typescript3.9 新特性内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!