还记得我在《2020 年 JavaScript 状态调研报告小结》中提到的 2020 年全球开发者最喜欢的 JavaScript 写法是什么吗?-- 没错!TypeScript!。鉴于在项目中使用 TypeScript 确实有如下种种好处:html
本篇文章将向您介绍 TypeScript 自 3.7 版本以来更新的一些实用特性,但愿您的代码能变得更加稳固,优雅。git
请注意,TypeScript 是 JavaScript 类型的超集,而非语法的超集,所以一些符合 JavaScript 语法规范的代码,在 TypeScript 中却可能报错,例如:程序员
let x = 1 x = 'hello world'
所以,在现代工具链中,TypeScript 编译器甚至不被用做编译出指定版本 JavaScript 的工具(这一般是 babel 的工做),而是做为一种更强大的代码检查工具被使用。可是随着 TypeScript 版本的更新,一些新的 JavaScript 语法特性也逐渐被 TypeScript 支持,这使得开发者在一些场景下能够摆脱 babel 编译的过程,直接使用 TypeScript 编译生成最终的代码。github
自 3.7 版本开始,TypeScript 支持了目前在 stage 4 阶段的 Optional Chaining ,Nullish Coalescing语法。typescript
自 3.8 版本开始,Typescript 支持了目前在 stage 3 阶段的 Private Fields 语法。(经过底层使用 WeakMap 数据结构,该语法使得 JavaScript 类真正意义上拥有「私有属性」)编程
class Foo { #bar }
同时,该版本还支持了 namespace exports 语法:后端
export * as utils from './utils'
自 4.0 版本开始,TypeScript 支持自动推导 class 中的属性类型,无需再显示声明。babel
TypeScript 4.0 开始支持两种新的元组类型声明方式:数据结构
type Foo<T extends any[]> = [boolean, ...T, boolean]
经过这种声明方式,咱们能够更精确的定义一个函数参数类型,在使用函数式编程时,这种定义方式就颇有用。编辑器
const Address = [string, number] function setAddress(...args: Address) { // some code here }
当咱们这样定义函数入参后,在使用函数时,编辑器的智能提示只会提示咱们参数类型,丢失了对参数含义的描述。为了改善这一点,咱们能够经过 Labeled tuple types,咱们能够这样定义参数:
const Address = [streetName: string, streetNumber: number] function setAddress(...args: Address) { // some code here }
这样,在调用函数时,咱们的参数就得到了相应的语义,这使得代码更加容易维护。
自 Typescript 3.7 开始,咱们终于得到了只用一条类型声明声明 JSON 数据的能力:
type JSONValue = | string | number | boolean | null | JSONValue[] | { [key: string]: JSONValue }
// @ts-expect-error
TypeScript 3.9 给出了一个替代 // @ts-ignore
注释的方案:// @ts-expect-error
。
从字面上咱们不难理解为何后者是更优的选择:
unknown
类型让咱们想一想这段代码会最终打印出什么:
try { willThrowAnError() } catch (err) { console.log(typeof err.message) }
答案是 "string"
吗,并不是如此!由于 err.message
的值有多是 undefined
,甚至有可能在这里抛错,这取决于咱们的函数 willThrowAnError
内部是如何定义的:
// err.message => undefined function willThrowAnError() { throw 'hello world' } // err.message => throw an Error! function willThrowAnError() { throw null }
虽然第二种状况几乎不会发生,但这两个示例说明了 catch
参数类型的不肯定性(所以在 TypeScript 中,它的默认类型是 any
)。
所以,在 TypeScript 4.0 中,提供了 unknown
类型供咱们处理这些咱们「不知道」的类型。不一样于 any
类型,unknown
是 TypeScript 中的第一类型,能够在任何地方使用。
子曰:知之为知之,不知为不知。
自 TypeScript 3.7 开始,支持基于 return/throw
的类型断言。
function assertIsArray(val: any): asserts val is any[] { if (!Array.isArray(val)) throw new Error(`${val} is not an array`) }
这将让测试变得更加容易。
点击此处浏览相关文档
自 TypeScript 3.8 开始,TypeScript 支持仅引入模块类型:
import type { SomeThing } from "./some-module.js"; export type { SomeThing };
这样作的好处在于,当某个模块中包含反作用代码时,用户若是直接引入模块,就会无心间执行反作用代码,但当经过声明只引入类型时,则避免了这个隐患。
点击此处浏览相关文档。
至此,本篇文章带您快速浏览了 TypeScript 3.7 以来一些实用性强的新特性,不知道您是否学有所获?TypeScript 将在 2021 年 5 月 25 日发布 4.3 版本,届时会新增哪些有意思的新特性?且听下回分解:)