TypeScript 3.7 发布,带来 Optional Chaining 等特性
TypeScript 3.7 发布了,此版本带来了许多新特性。
Optional Chaining
首先一大亮点是 Optional Chaining,这是社区呼唤特别强烈的一个 ECMAScript 特性。最初它是 TypeScript 的 issue 跟踪器上第 16 个 issue,于 5 年前提交,要知道目前总共有多达 23000 个 issue。当时 TC39 还没有正式提案,这些年来开发者一直要求实现该特性,但是为了不与 ECMAScript 建议冲突,迟迟没有实现,相反 TS 开发团队一直在帮助推动该提案实现标准化,并最终推及所有 JavaScript 与 TypeScript 开发者。
Optional Chaining 特性主要用于保护出现在属性路径中 null 和 undefined 值,像 C# 等语言中已经有用于访问属性链的语法糖,可以在对象层次结构中的任何地方处理遇到的 null 和 undefined 情况,使它可以正常执行,而不会抛出错误。
具体来讲,在向树状结构深处进行属性值访问时,通常需要检查中间节点是否存在:
var street = user.address && user.address.street;
许多 API 返回一个对象或 null/undefined,并且可能只想在结果不为 null 时从结果中提取属性:
var fooInput = myForm.querySelector('input[name=foo]') var fooValue = fooInput ? fooInput.value : undefined
Optional Chaining 运算符允许开发人员直接用简单的方式处理这种情况,而不用进行重复性操作,或者使用临时变量分配中间结果:
var street = user.address?.street var fooValue = myForm.querySelector('input[name=foo]')?.value
因为是保护访问属性链时的 null 与 undefined,所以 Optional Chaining 运算符也叫做“安全导航运算符”,TC39 标准中给出的该运算符是“?.”,它的语法可以适用于三种场景:
obj?.prop // 自判断静态属性访问 obj?.[expr] // 自判断动态访问 func?.(...args) // 自判断函数或方法调用
null 判断合并(Nullish Coalescing)
另一个与 Optional Chaining 很接近的特性是 null 判断合并(Nullish Coalescing),由特定的 Nullish Coalescing 操作符 ?? 启用,它也是即将到来的 ECMAScript 特性。
考虑以下代码:
let x = (foo !== null && foo !== undefined) ? foo : bar();
如果 foo 不为空并且不等于 undefined,则执行 bar()。它现在可以等效于:
let x = foo ?? bar();
断言
如果发生意外情况,则有一组特定函数会抛出错误,这被称为断言。例如 Node.js 有一个专用的 assert 函数:
assert(someValue === 42);
如果 someValue 不等于 42,则 assert 将抛出 AssertionError。
JavaScript 中的断言通常用于防止传入不正确的类型,例如:
function multiply(x, y) { assert(typeof x === "number"); assert(typeof y === "number"); return x * y; }
不过在 TypeScript 中,会有一些类型问题:
function yell(str) { assert(typeof str === "string"); return str.toUppercase(); // Oops! We misspelled 'toUpperCase'. // Would be great if TypeScript still caught this! }
替代方法是改写代码,以便语言可以对其进行分析,但这不太方便:
function yell(str) { if (typeof str !== "string") { throw new TypeError("str should have been a string.") } // Error caught! return str.toUppercase(); }
TypeScript 希望以最小的破坏性方式保留现有 JavaScript 结构,因此 TypeScript 3.7 引入了一个称为“断言签名”的新概念,可以对这些断言函数进行建模。
第一种断言签名对 Node.js assert 的执行方式进行建模,它确保在包含范围的其余部分中,无论检查什么条件都必须为真。
function assert(condition: any, msg?: string): asserts condition { if (!condition) { throw new AssertionError(msg) } }
assert condition 表示,如果 assert 返回,则传递给 condition 参数的任何内容都必须为 true(否则会引发错误),这意味着对于其余范围,该条件必须是 true。
以前边的 yell 为例,确实可以捕获到类型错误:
function yell(str) { assert(typeof str === "string"); return str.toUppercase(); // ~~~~~~~~~~~ // error: Property 'toUppercase' does not exist on type 'string'. // Did you mean 'toUpperCase'? } function assert(condition: any, msg?: string): asserts condition { if (!condition) { throw new AssertionError(msg) } }
另一种断言签名不检查条件,而是告诉 TypeScript 特定的变量或属性具有不同的类型。
function assertIsString(val: any): asserts val is string { if (typeof val !== "string") { throw new AssertionError("Not a string!"); } }
这里的 assert val is string,确保在对 assertIsString 进行任何调用之后,传入的任何变量都将是字符串。
function yell(str: any) { assertIsString(str); // Now TypeScript knows that 'str' is a 'string'. return str.toUppercase(); // ~~~~~~~~~~~ // error: Property 'toUppercase' does not exist on type 'string'. // Did you mean 'toUpperCase'? }
这些断言签名与编写类型谓词签名非常相似:
function isString(val: any): val is string { return typeof val === "string"; } function yell(str: any) { if (isString(str)) { return str.toUppercase(); } throw "Oops!"; }
类似类型谓词签名,这些断言签名也具有很强的表现力,可以用这些表达一些相当复杂的逻辑:
function assertIsDefined<T>(val: T): asserts val is NonNullable<T> { if (val === undefined || val === null) { throw new AssertionError( `Expected 'val' to be defined, but received ${val}` ); } }
此外还有其它新特性与特性增强,详情查看更新说明:
https://devblogs.microsoft.com/typescript/announcing-typescript-3-7
另外,作为更新的一部分,TypeScript 官网还有一个游乐场(Playground)可以体验所有新特性:
https://www.typescriptlang.org/play/index.html?#show-whatisnew
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
OpenIndiana 2019.10 发布,OpenSolaris 的社区发行版
OpenIndiana 2019.10发布了,内容如下: 将 IPS 打包系统切换到 Python3,并根据 OmniOSCE 2019.08 中的内容进行更新 更多的 OpenIndiana 特定软件已经从 Python 2.7 迁移到 Python 3.5 重写了 DDU 二进制 BLOB,更新了驱动程序数据库 并且它的包集合做了很多更新,包更新包括更新 GCC 编译器,添加 Clang 8.0 选项,更新 VirtualBox 版本,更新 GTK 3 和许多其他更新 详情见发布说明。
- 下一篇
Calibre 4.3.0 发布,电子书管理软件
Calibre 4.3.0已发布,更新内容有: Viewer: 添加带有常见操作的可选工具栏,在Preferences->Miscellaneous下将其打开 将默认配色方案更改为“System” 添加键盘快捷方式;进入图书位置 添加一个控件,以便将接口重置为默认值 添加命令行选项强制重新加载书籍 Bug fixes: Content server:修复漫画转换无效 Book details:允许右击复制作者链接和标识符、修复通过右击移除标识符无效、修复单击标记等不能生成精确匹配的搜索 Viewer:当调整大小时,确保在分页模式下返回到相同的页面 Duplicates dialog:根据作者的要求,对匹配的书籍进行排序,以便于查阅 PDF Output:修复指向同一文件中的目标的链接不起作用 DOCX Input:修复了 AlternateContent 块,渲染选择部分和回退部分 Viewer:修复在导航到 CFI 时的异常 修复在下载封面时取消图标主题下载出现的崩溃 Viewer:修复样式表中未正确解释的非 ASCII 内容 更多内容请见发布说明。
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS7安装Docker,走上虚拟化容器引擎之路
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装