当前位置:首页 > 科技  > 软件

TypeScript 5.3 来了,一大波新特性

来源: 责编: 时间:2023-11-16 09:39:51 389观看
导读根据 TypeScript 路线图,TypeScript 5.3 计划于 11 月 14 日发布。下面是该版本带来的新特性:导入属性导入类型中稳定支持 resolution-mode所有模块模式均支持 resolution-modeswitch (true) 缩小范围对布尔值进行比较

bPu28资讯网——每日最新资讯28at.com

根据 TypeScript 路线图,TypeScript 5.3 计划于 11 月 14 日发布。bPu28资讯网——每日最新资讯28at.com

图片bPu28资讯网——每日最新资讯28at.com

下面是该版本带来的新特性:bPu28资讯网——每日最新资讯28at.com

  • 导入属性
  • 导入类型中稳定支持 resolution-mode
  • 所有模块模式均支持 resolution-mode
  • switch (true) 缩小范围
  • 对布尔值进行比较的缩小范围
  • 通过 Symbol.hasInstance 进行 instanceof 类型缩小
  • 实例字段上的 super 属性访问检查
  • 嵌入提示支持跳转到类型的定义
  • 通过跳过 JSDoc 解析进行优化
  • 通过比较非标准交集进行优化
  • 整合 tsserverlibrary.js 和 typescript.js

导入属性

TypeScript 5.3 支持导入属性提案的最新更新。导入属性的一个用例是向运行时提供有关模块的预期格式的信息。bPu28资讯网——每日最新资讯28at.com

// 希望将这个文件解释为 JSON 数据,而不是一个带有 .json 扩展名的可执行/恶意的 JavaScript 文件。import obj from "./something.json" with { type: "json" };

这些属性的内容不会被 TypeScript 检查,因为它们是特定于宿主环境的,并且会被直接保留,以便浏览器和运行时环境可以处理它们(并可能会出现错误)。bPu28资讯网——每日最新资讯28at.com

// TypeScript 对此没有问题,但是浏览器可能不支持。import * as foo from "./foo.js" with { type: "fluffy bunny" };

动态 import() 调用还可以通过第二个参数使用导入属性。bPu28资讯网——每日最新资讯28at.com

const obj = await import("./something.json", {    with: { type: "json" }});

第二个参数的预期类型由名为 ImportCallOptions 的类型定义,该类型默认情况下只需要一个名为 with 的属性。bPu28资讯网——每日最新资讯28at.com

注意,导入属性是早期提案“导入断言”的演进版本,该提案已在 TypeScript 4.5 中实现。最明显的区别是使用 with 关键字而不是 assert 关键字。但不太明显的区别在于,现在运行时可以自由地使用属性来引导导入路径的解析和解释,而导入断言只能在加载模块后断言某些特征。bPu28资讯网——每日最新资讯28at.com

随着时间的推移,TypeScript 将逐渐弃用旧的导入断言语法,并倾向于使用导入属性的提案语法。现有使用 assert 的代码应该迁移到使用 with 关键字。需要使用导入属性的新代码应该使用 with。bPu28资讯网——每日最新资讯28at.com

resolution-mode

导入类型中稳定支持 resolution-mode

在 TypeScript 4.7 中,TypeScript 增加了对 /// <reference types="..." /> 中的 resolution-mode 属性的支持,以控制特定规范符号是应该通过 import 还是 require 语义进行解析。bPu28资讯网——每日最新资讯28at.com

/// <reference types="pkg" resolution-mode="require" />// 或/// <reference types="pkg" resolution-mode="import" />

考虑到导入属性可以引导解析,并且已经看到了合理的使用案例,TypeScript 5.3 现在支持 import type 的 resolution-mode 属性。bPu28资讯网——每日最新资讯28at.com

// 以使用 `require()` 进行导入的方式解析 `pkg`import type { TypeFromRequire } from "pkg" with {  "resolution-mode": "require"};// 以使用 `import` 进行导入的方式解析 `pkg`import type { TypeFromImport } from "pkg" with {  "resolution-mode": "import"};export interface MergedType extends TypeFromRequire, TypeFromImport {}

这些导入属性也可以用于 import() 类型。bPu28资讯网——每日最新资讯28at.com

export type TypeFromRequire =  import("pkg", { with: { "resolution-mode": "require" } }).TypeFromRequire;export type TypeFromImport =  import("pkg", { with: { "resolution-mode": "import" } }).TypeFromImport;export interface MergedType extends TypeFromRequire, TypeFromImport {}

所有模块模式均支持 resolution-mode

以前,只有在 moduleResolution 选项为 node16 和 nodenext 时才允许使用 resolution-mode。为了更容易地专门查找用于类型的模块,现在 resolution-mode 在所有其他 moduleResolution 选项中都能正常工作,比如 bundler、node10,在 classic 模式下则不会报错。bPu28资讯网——每日最新资讯28at.com

类型缩小优化

switch (true)

现在 TypeScript 5.3 能够根据 switch 中每个 case 子句的条件进行类型细化。bPu28资讯网——每日最新资讯28at.com

function f(x: unknown) {    switch (true) {        case typeof x === "string":            // 这里,'x' 是一个 'string'            console.log(x.toUpperCase());        case Array.isArray(x):            // 这里 'x' 是一个 'string | any[]'            console.log(x.length);        default:          // 这里 'x' 是 'unknown'          // ...    }}

布尔值比较

有时候你可能会在条件语句中直接与 true 或 false 进行比较。通常这些比较是不必要的,但可能出于代码风格或避免 JavaScript 真值方面的某些问题而偏好这种写法。然而,在之前的 TypeScript 版本中,它不能正确地识别这种形式来执行类型缩小。bPu28资讯网——每日最新资讯28at.com

TypeScript 5.3 现在在缩小变量范围时可以跟上并理解这些表达式。bPu28资讯网——每日最新资讯28at.com

interface A {    a: string;}interface B {    b: string;}type MyType = A | B;function isA(x: MyType): x is A {    return "a" in x;}function someFn(x: MyType) {    if (isA(x) === true) {        console.log(x.a); // works!    }}

Symbol.hasInstance

JavaScript 的一个特性是可以重写 instanceof 运算符的行为。要实现这一点,需要在 instanceof 运算符右侧的值上定义一个名为 Symbol.hasInstance 的特定方法。bPu28资讯网——每日最新资讯28at.com

class Weirdo {    static [Symbol.hasInstance](testedValue) {        return testedValue === undefined;    }}// falseconsole.log(new Thing() instanceof Weirdo);// trueconsole.log(undefined instanceof Weirdo);

为了更好地模拟 instanceof 运算符的行为,TypeScript 现在会检查是否存在 [Symbol.hasInstance] 方法,并且该方法被声明为类型断言函数。如果存在这样的方法,那么通过 instanceof 运算符对左侧测试的值将会被相应地进行类型缩小。bPu28资讯网——每日最新资讯28at.com

interface PointLike {    x: number;    y: number;}class Point implements PointLike {    x: number;    y: number;    constructor(x: number, y: number) {        this.x = x;        this.y = y;    }    distanceFromOrigin() {        return Math.sqrt(this.x ** 2 + this.y ** 2);    }    static [Symbol.hasInstance](val: unknown): val is PointLike {        return !!val && typeof val === "object" &&            "x" in val && "y" in val &&            typeof val.x === "number" &&            typeof val.y === "number";    }}function f(value: unknown) {    if (value instanceof Point) {        // 可以访问这两个属性 - 正确!        value.x;        value.y;        // 无法访问这个属性,有 'PointLike' 类型的对象,但实际上并没有 'Point' 类型的对象。        value.distanceFromOrigin();    }}

在这个例子中,Point 定义了自己的 [Symbol.hasInstance]方法。它实际上充当了一个对称为 PointLike 的独立类型的自定义类型保护程序。在函数 f 中,我们能够通过 instanceof 将 value 缩小到 PointLike 类型,但无法缩小到 Point 类型。这意味着可以访问属性 x 和 y,但无法访问 distanceFromOrigin 方法。bPu28资讯网——每日最新资讯28at.com

实例字段上的 super 属性访问检查

在 JavaScript 中,可以通过 super 关键字访问基类中的声明。bPu28资讯网——每日最新资讯28at.com

class Base {    someMethod() {        console.log("Base method called!");    }}class Derived extends Base {    someMethod() {        console.log("Derived method called!");        super.someMethod();    }}new Derived().someMethod();// 输出结果://   Derived method called!//   Base method called!

这与编写像 this.someMethod() 这样的代码是不同的,因为那样可能会调用一个被重写的方法,如果一个声明根本没有被重写,那么通常这两种方式是可以互换的。bPu28资讯网——每日最新资讯28at.com

class Base {    someMethod() {        console.log("someMethod called!");    }}class Derived extends Base {    someOtherMethod() {        // These act identically.        this.someMethod();        super.someMethod();    }}new Derived().someOtherMethod();// 输出结果://   someMethod called!//   someMethod called!

问题在于这两种方式是不能互换使用的,因为 super 只能用于在原型上声明的成员,而不能用于实例属性。这意味着如果你写了 super.someMethod(),但 someMethod 被定义为一个字段,那么就会出现运行时错误!bPu28资讯网——每日最新资讯28at.com

class Base {    someMethod = () => {        console.log("someMethod called!");    }}class Derived extends Base {    someOtherMethod() {        super.someMethod();    }}new Derived().someOtherMethod();

TypeScript 5.3 现在更仔细地检查 super 属性访问/方法调用,以查看它们是否对应于类字段。如果是的话,现在会得到一个类型检查错误。bPu28资讯网——每日最新资讯28at.com

嵌入提示支持跳转到类型的定义

TypeScript 的嵌入提示现在支持跳转到类型的定义!bPu28资讯网——每日最新资讯28at.com

bPu28资讯网——每日最新资讯28at.com

按住 Ctrl 键单击嵌入提示可跳转至参数类型的定义。bPu28资讯网——每日最新资讯28at.com

通过跳过 JSDoc 解析进行优化

通过 tsc 运行 TypeScript 时,编译器现在将避免解析 JSDoc。这不仅减少了解析时间,还减少了存储注释的内存使用量以及垃圾收集所花费的时间。可以在 --watch 模式下看到稍快的编译速度和更快的反馈。bPu28资讯网——每日最新资讯28at.com

通过比较非标准交集进行优化

在 TypeScript 中,并集和交集始终遵循特定的形式,其中交集不能包含并集类型。这意味着当我们在 A & (B | C) 这样的并集上创建交集时,该交集将被标准化为 (A & B) | (A & C)。尽管如此,在某些情况下,类型系统仍会出于显示目的而保留原始形式。bPu28资讯网——每日最新资讯28at.com

举个例子,假设我们有 SomeType & (Type1 | Type2 | ... | Type99999NINE),我们想要确定它是否可以赋值给 SomeType,源类型是一个看起来像 (SomeType & Type1) | (SomeType & Type2) | ... |(SomeType & Type99999NINE) 的联合类型。在检查一个联合类型是否可以赋值给某个目标类型时,必须检查联合类型的每个成员是否可以赋值给目标类型,这可能会非常慢。bPu28资讯网——每日最新资讯28at.com

在 TypeScript 5.3 中,当比较类型时,会快速检查目标类型是否存在于源交集中的任何成员中。bPu28资讯网——每日最新资讯28at.com

整合 tsserverlibrary.js 和 typescript.js

TypeScript 本身提供了两个库文件:tsserverlibrary.js 和 typescript.js。在 tsserverlibrary.js 中只有特定的 API(例如 ProjectService API)。然而,这两个是不同包,它们有许多重叠之处,在包中重复了很多代码。更重要的是,由于自动导入或肌肉记忆,要始终一致地使用其中一个可能会很具有挑战性。意外加载两个模块太容易了,代码在不同的 API 实例上可能无法正常工作。即使它能够正常工作,加载第二个包会增加资源使用率。bPu28资讯网——每日最新资讯28at.com

鉴于此,TypeScript 团队决定整合两者。 typescript.js 现在包含 tsserverlibrary.js 的内容,并且 tsserverlibrary.js 现在只是重新导出 typescript.js。整合之后,包大小减少了 20.5%。bPu28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-26564-0.htmlTypeScript 5.3 来了,一大波新特性

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 怎么理解 React Server Component 和 Next.js 的关系

下一篇: 线程剖析 - 助力定位代码层面高耗时问题

标签:
  • 热门焦点
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • 6月iOS设备好评榜:第一蝉联榜首近一年

    作为安兔兔各种榜单里变化最小的那个,2023年6月的iOS好评榜和上个月相比没有任何排名上的变化,仅仅是部分设备好评率的下降,长年累月的用户评价和逐渐退出市场的老款机器让这
  • Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • 不容错过的MSBuild技巧,必备用法详解和实践指南

    一、MSBuild简介MSBuild是一种基于XML的构建引擎,用于在.NET Framework和.NET Core应用程序中自动化构建过程。它是Visual Studio的构建引擎,可在命令行或其他构建工具中使用
  • 本地生活这块肥肉,拼多多也想吃一口

    出品/壹览商业 作者/李彦编辑/木鱼拼多多也看上本地生活这块蛋糕了。近期,拼多多在App首页&ldquo;充值中心&rdquo;入口上线了本机生活界面。壹览商业发现,该界面目前主要
  • 网传小米汽车开始筛选交付中心 建筑面积不低于3000平方米

    7月7日消息,近日有微博网友@长三角行健者爆料称,据经销商集团反馈,小米汽车目前已经开始了交付中心的筛选工作,要求候选场地至少有120个车位,建筑不能低
  • 朋友圈可以修改可见范围了 苹果用户可率先体验

    近日,iOS用户迎来微信8.0.27正式版更新,除了可更换二维码背景外,还新增了多项实用功能。在新版微信中,朋友圈终于可以修改可见范围,简单来说就是已发布的朋友圈
  • Meta盲目扩张致超万人被裁,重金押注元宇宙而前景未明

    图片来源:图虫创意日前,Meta创始人兼CEO 马克&middot;扎克伯发布公开信,宣布Meta计划裁员超11000人,占其员工总数13%。他公开承认了自己的预判失误:&ldquo;不仅
  • 北京:科技教育体验基地开始登记

      北京“科技馆之城”科技教育体验基地登记和认证工作日前启动。首批北京科技教育体验基地拟于2023年全国科普日期间挂牌,后续还将开展常态化登记。  北京科技教育体验基
Top