TypeScript 3.7 最新实用特性解读

Posted 阿里巴巴淘系技术团队官网博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript 3.7 最新实用特性解读相关的知识,希望对你有一定的参考价值。

还记得我在《2020 年 javascript 状态调研报告小结》中提到的 2020 年全球开发者最喜欢的 JavaScript 写法是什么吗?

没错!TypeScript!。

鉴于在项目中使用 TypeScript 确实有以下种种好处:

  1. 帮助开发者在「代码撰写时」(结合编辑器)而非「代码运行时」及时感知类型/语法错误(⚠️ 注意,TypeScript 并非万能,它并不能帮助您捕捉请求错误或环境错误);

  2. 结合编辑器,提供智能提示,提升开发体验;

  3. 很少被提及的一点:更容易让服务端程序员理解代码,方便前后端交流;

本篇文章将向您介绍 TypeScript 自 3.7 版本以来更新的一些实用特性,希望您的代码能变得更加稳固,优雅。


新支持特性

请注意,TypeScript 是 JavaScript 类型的超集,而非语法的超集,因此一些符合 JavaScript 语法规范的代码,在 TypeScript 中却可能报错,例如:

let x = 1
x = 'hello world'

因此,在现代工具链中,TypeScript 编译器甚至不被用作编译出指定版本 JavaScript 的工具(这通常是 babel 的工作),而是作为一种更强大的代码检查工具被使用。但是随着 TypeScript 版本的更新,一些新的 JavaScript 语法特性也逐渐被 TypeScript 支持,这使得开发者在一些场景下可以摆脱 babel 编译的过程,直接使用 TypeScript 编译生成最终的代码。


  Optional Chaining & Nullish Coalescing


自 3.7 版本开始,TypeScript 支持了目前在 stage 4 阶段的 Optional Chaining ,Nullish Coalescing语法。

Optional Chaining:https://github.com/tc39/proposal-optional-chaining?spm=ata.21736010.0.0.4b9349ebW4f9Iy

Nullish Coalescing:https://github.com/tc39/proposal-nullish-coalescing?spm=ata.21736010.0.0.4b9349ebW4f9Iy

  Private Fields && Namespace exports


自 3.8 版本开始,Typescript 支持了目前在 stage 3 阶段的 Private Fields 语法。(通过底层使用 WeakMap 数据结构,该语法使得 JavaScript 类真正意义上拥有「私有属性」)

Private Fields:https://github.com/tc39/proposal-class-fields?spm=ata.21736010.0.0.4b9349ebW4f9Iy#private-fields

class Foo {
  #bar
}

同时,该版本还支持了 namespace exports 语法:

export * as utils from './utils'


  Inference of class field types


自 4.0 版本开始,TypeScript 支持自动推导 class 中的属性类型,无需再显示声明。


新类型:元组

TypeScript 4.0 开始支持两种新的元组类型声明方式:

  1. Variadic tuple types(可变元组类型)

  2. Labeled tuple types(命名元组类型)


  可变元组类型


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。

从字面上我们不难理解为什么后者是更优的选择:

  1. 显示声明了会报错的原因,而不只是一味的规避检查;

  2. 向前兼容,未来如果 TypeScript 支持某语法导致不再报错,TypeScript 会主动提示删除注释,这会让代码变得更加简洁;


  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 中的第一类型,可以在任何地方使用。

子曰:知之为知之,不知为不知。


  Assertion functions


自 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`)
}

这将让测试变得更加容易。

点击此处浏览相关文档:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html?spm=ata.21736010.0.0.4b9349ebW4f9Iy#assertion-functions


模块


  Type-only imports


自 TypeScript 3.8 开始,TypeScript 支持仅引入模块类型:

import type { SomeThing } from "./some-module.js";


export type { SomeThing };

这样做的好处在于,当某个模块中包含副作用代码时,用户如果直接引入模块,就会无意间执行副作用代码,但当通过声明只引入类型时,则避免了这个隐患。

点击此处浏览相关文档:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html?spm=ata.21736010.0.0.4b9349ebW4f9Iy


小结

至此,本篇文章带您快速浏览了 TypeScript 3.7 以来一些实用性强的新特性,不知道您是否学有所获?TypeScript 将在 2021 年 5 月 25 日发布 4.3 版本,届时会新增哪些有意思的新特性?且听下回分解:)

✿  拓展阅读

作者|空堂

编辑|橙子君

出品|阿里巴巴新零售淘系技术

以上是关于TypeScript 3.7 最新实用特性解读的主要内容,如果未能解决你的问题,请参考以下文章

如何添加 TypeScript 3.7 可选链接支持来创建反应应用项目

Koa2实用入门

原创 | Java 13 明天发布,最新最全新特性解读

可选链与空值合并

Bootstrap ~3.7 和最新 Bootstrap (4) 之间简单代码的样式问题

Spring Boot 3.0正式发布及新特性解读