当前位置:首页 > 编程语言 > 正文内容

TypeScript 5.0中的新特性: 声明器、构造类型、枚举改进、速度以及更多内容

a811625533年前 (2023-04-19)编程语言19

TypeScript 5.0于2023年3月16日正式发布,现在可以供大家使用了。这个版本引入了许多新功能,目的是使TypeScript更小、更简单、更快速。

这个新版本对用于类定制的装饰器进行了现代化处理,允许以可重复使用的方式定制类和其成员。开发人员现在可以在类型参数声明中添加一个const修饰符,允许类似const的推断成为默认的。新版本还使所有枚举成为union枚举,简化了代码结构,加快了TypeScript的体验。

在这篇文章中,你将探索TypeScript 5.0中引入的变化,深入了解其新特性和功能。

开始使用TypeScript 5.0

TypeScript 是一个官方编译器,你可以使用 npm 安装到你的项目中。如果你想在你的项目中开始使用TypeScript 5.0,你可以在你的项目目录中运行以下命令:

npm install -D typescript

这将在node_modules目录下安装编译器,现在你可以用 npx tsc 命令运行它。

你还可以在中找到关于在Visual Studio Code中使用较新版本TypeScript的说明。

TypeScript 5.0 有哪些新特性?

在这篇文章中,让我们来探讨TypeScript中引入的5个主要更新。这些功能包括:

现代化的装饰器

装饰器在TypeScript中已经存在了一段时间,但新版本使其与ECMAScript的提议保持一致,现在处于,这意味着它处于被添加到TypeScript的阶段。

装饰器是一种以可重复使用的方式定制类和其成员的行为的 *** 。例如,如果你有一个类,它有两个 *** , greetgetAge

class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
getAge() {
console.log(`I am ${this.age} years old.`);
}
}
const p = new Person('Ron', 30);
p.greet();
p.getAge();

在现实世界的用例中,这个类应该有更复杂的 *** 来处理一些异步逻辑,并有副作用,例如,你会想扔进一些 console.log 调用来帮助调试 *** 。

class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet() {
console.log('LOG: Method Execution Starts.');
console.log(`Hello, my name is ${this.name}.`);
console.log('LOG: Method Execution Ends.');
}
getAge() {
console.log('LOG: Method Execution Starts.');
console.log(`I am ${this.age} years old.`);
console.log('Method Execution Ends.');
}
}
const p = new Person('Ron', 30);
p.greet();
p.getAge();

这是一个经常出现的模式,如果有一个适用于每一个 *** 的解决方案,那就很方便了。

这就是装饰器发挥作用的地方。我们可以定义一个名为 debugMethod 的函数,如下所示:

function debugMethod(originalMethod: any, context: any) {
function replacementMethod(this: any, ...args: any[]) {
console.log('Method Execution Starts.');
const result = originalMethod.call(this, ...args);
console.log('Method Execution Ends.');
return result;
}
return replacementMethod;
}

在上面的代码中, debugMethod 接收原始 *** ( originalMethod ),并返回一个函数,做以下工作:

  1. 记录 “Method Execution Starts.” 的信息。
  2. 传递原始 *** 和它的所有参数(包括这个)。
  3. 记录一条消息 “Method Execution Ends.”。
  4. 返回原始 *** 返回的东西。

通过使用装饰器,你可以将 debugMethod 应用到你的 *** 中,如下面的代码所示:

class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
@debugMethod
greet() {
console.log(`Hello, my name is ${this.name}.`);
}
@debugMethod
getAge() {
console.log(`I am ${this.age} years old.`);
}
}
const p = new Person('Ron', 30);
p.greet();
p.getAge();

这将输出以下内容:

LOG: Entering method.
Hello, my name is Ron.
LOG: Exiting method.
LOG: Entering method.
I am 30 years old.
LOG: Exiting method.

在定义装饰函数( debugMethod )时,会传递第二个参数,叫做 context (它是context对象–有一些关于装饰 *** 如何被声明的有用信息,也有 *** 的名称)。你可以更新你的 debugMethod ,从 context 对象中获取 *** 的名称:

function debugMethod(
originalMethod: any,
context: ClassMethodDecoratorContext
) {
const methodName = String(context.name);
function replacementMethod(this: any, ...args: any[]) {
console.log(`'${methodName}' Execution Starts.`);
const result = originalMethod.call(this, ...args);
console.log(`'${methodName}' Execution Ends.`);
return result;
}
return replacementMethod;
}

当你运行你的代码时,现在输出将带有每个用 debugMethod 装饰器装饰的 *** 的名字:

'greet' Execution Starts.
Hello, my name is Ron.
'greet' Execution Ends.
'getAge' Execution Starts.
I am 30 years old.
'getAge' Execution Ends.

你可以用装饰器做的事情还有很多。请随时查看,以获得更多关于如何在TypeScript中使用装饰器的信息。

引入const类型参数

这是另一个重要的版本,它为你提供了一个新的泛型工具,以改善你在调用函数时得到的推断。默认情况下,当你用 const 声明值时,TypeScript会推断出类型而不是其字面值:

// Inferred type: string[]
const names = ['John', 'Jake', 'Jack'];

直到现在,为了实现所需的推理,你不得不通过添加 “as const “来使用const断言:

// Inferred type: readonly ["John", "Jake", "Jack"]
const names = ['John', 'Jake', 'Jack'] as const;

当你调用函数时,情况类似。在下面的代码中,推断出的countries的类型是 string[]

type HasCountries = { countries: readonly string[] };
function getCountriesExactly(arg: T): T['countries'] {
return arg.countries;
}
// Inferred type: string[]
const countries = getCountriesExactly({ countries: ['USA', 'Canada', 'India'] });

你可能希望有一个更具体的类型,在这之前,有一种 *** 可以解决这个问题,那就是添加 as const 断言:

// Inferred type: readonly ["USA", "Canada", "India"]
const names = getNamesExactly({ countries: ['USA', 'Canada', 'India'] } as const);

这可能很难记住和实现。然而,TypeScript 5.0引入了一个新的功能,你可以在类型参数声明中添加一个const修饰符,这将自动应用一个类似const的默认推理。

type HasCountries = { countries: readonly string[] };
function getNamesExactly(arg: T): T['countries'] {
return arg.countries;
}
// Inferred type: readonly ["USA", "Canada", "India"]
const names = getNamesExactly({ countries: ['USA', 'Canada', 'India'] });

使用 const 类型参数可以让开发者在他们的代码中更清楚地表达意图。如果一个变量打算成为常量,并且永远不会改变,那么使用 const 类型参数可以确保它永远不会被意外地改变。

你可以查看,了解更多关于const类型参数在TypeScript中的工作原理。

对枚举的改进

TypeScript 中的枚举是一个强大的结构,允许开发者定义一组命名的常量。在TypeScript 5.0中,对枚举进行了改进,使其更加灵活和有用。

例如,如果你有以下枚举传入一个函数:

enum Color {
Red,
Green,
Blue,
}
function getColorName(colorLevel: Color) {
return colorLevel;
}
console.log(getColorName(1));

在引入TypeScript 5.0之前,你可以传递一个错误的级别号,而且它不会抛出错误。但随着TypeScript 5.0的引入,它将立即抛出一个错误。

此外,新版本通过为每个计算成员创建一个独特的类型,使所有枚举成为联合枚举。这一改进允许缩小所有枚举的范围,并将其成员作为类型进行引用:

enum Color {
Red,
Purple,
Orange,
Green,
Blue,
Black,
White,
}
type PrimaryColor = Color.Red | Color.Green | Color.Blue;
function isPrimaryColor(c: Color): c is PrimaryColor {
return c === Color.Red || c === Color.Green || c === Color.Blue;
}
console.log(isPrimaryColor(Color.White)); // Outputs: false
console.log(isPrimaryColor(Color.Red)); // Outputs: true

TypeScript 5.0的性能改进

TypeScript 5.0 包括代码结构、数据结构和算法扩展方面的众多重大变化。这有助于改善整个 TypeScript 体验,从安装到执行,使其更快、更高效。

例如,TypeScript 5.0和4.9的包大小之间的差异是相当惊人的。

TypeScript最近从命名空间迁移到了模块,使其能够利用现代构建工具,可以进行范围提升等优化。此外,删除了一些废弃的代码,从TypeScript 4.9的63.8 MB包大小中减少了约26.4 MB。

TypeScript包的大小

下面是TypeScript 5.0和4.9之间在速度和大小上的一些更有趣的对比:

场景 相对于TS 4.9的时间或大小
material-ui构建时间 90%
TypeScript编译器的启动时间 89%
Playwright构建时间 88%
TypeScript Compiler自建时间 87%
Outlook Web构建时间 82%
VS Code构建时间 80%
typescript npm包大小 59%

捆绑器解决更好的模块解析

当你在TypeScript中写一个导入语句时,编译器需要知道这个导入指的是什么。它使用模块解析来实现这一点。例如,当你写 import { a } from "moduleA" 时,编译器需要知道 moduleAa 的定义以检查其使用。

在TypeScript 4.7中,为 --module 和 moduleResolution 设置增加了两个新选项: node16nodenext

这些选项的目的是为了更准确地表示中ECMAScript模块的精确查找规则。然而,这种模式有几个限制,是其他工具所不能执行的。

例如,在Node.js中的ECMAScript模块中,任何相对导入都必须包括一个文件扩展名才能正确工作:

import * as utils from "./utils"; // Wrong 
import * as utils from "./utils.mjs"; // Correct

TypeScript引入了一个新的策略,叫做 “moduleResolution bundler”。这个策略可以通过在你的TypeScript配置文件的 “compilerOptions “部分添加以下代码来实现:

{
"compilerOptions": {
"target": "esnext",
"moduleResolution": "bundler"
}
}

这个新策略适用于那些使用现代捆绑器的人,如Vite、e *** uild、swc、Webpack、Parcel和其他利用混合查找策略的捆绑器。

你可以查看及其实现,以了解更多关于 moduleResolution 捆绑器在TypeScript中如何工作的信息。

变动和弃用

TypeScript 5.0新增了部分变动和弃用,包括运行时间要求、lib.d.ts 更改和 API 突破性更改。

  1. 运行时要求: TypeScript现在以ECMAScript 2018为目标,该包设定的更低引擎期望值为12.20。因此,Node.js的用户应该至少有12.20或更高的版本来使用TypeScript 5.0。
  2. lib.d.ts的变化: 对于如何生成DOM的类型有一些变化,这可能会影响到现有的代码。特别是,某些属性已经从数字转换为数字字面类型,用于剪切、复制和粘贴事件处理的属性和 *** 已经跨接口移动。
  3. API的突破性变化: 一些不必要的接口已被删除,并进行了一些正确性的改进。TypeScript 5.0也已经转移到了模块。

TypeScript 5.0已经废弃了某些设置和它们相应的值,包括目标: target: ES3outnoImplicitUseStrictkeyofStringsOnlysuppressExcessPropertyErrorssuppressImplicitAnyIndexErrorsnoStrictGenericCheckscharsetimportsNotUsedAsValues, 和 preserveValueImports,以及项目引用中的prepend。

虽然这些配置在TypeScript 5.5之前仍然有效,但我们会发出警告,提醒仍在使用这些配置的用户。

小结

在这篇文章中,你已经了解了TypeScript 5.0带来的一些主要功能和改进,比如对枚举、捆绑器解析和常量类型参数的改进,以及对速度和大小的改进。

扫描二维码推送至手机访问。

版权声明:本文由2345好导航站长资讯发布,如需转载请注明出处。

本文链接:http://2345hao.cn/blog/index.php/post/7990.html

分享给朋友:

“TypeScript 5.0中的新特性: 声明器、构造类型、枚举改进、速度以及更多内容” 的相关文章

什么是JavaScript?网络上最流行的脚本语言一瞥

什么是JavaScript?网络上最流行的脚本语言一瞥

谁在尝试访问某些网站时没有遇到过更新Java的请求? 虽然许多人通过交互式网站功能熟悉Java,但用户可能不太熟悉JavaScript——或者,实际上,他们可能错误地认为两者是相同的。 在本文中,我们将讨论JavaScript 是什么以及Java和JavaScript之间的区别。然后我们将概...

宝塔面板教程之安装及常见问题篇

宝塔面板教程之安装及常见问题篇

宝塔面板现在已经成为国内许多站长必备的服务器管理必备工具。相比直接使用SSH+FTP来管理服务器,宝塔面板可以提供可视化管理,包括文件管理、数据库管理、数据备份、SSL配置等等。 如果你希望更简单高效地管理您的网站及服务器,宝塔面板是不错的选择。下面是一些宝塔面板安装及常见问题:...

宝塔面板教程之文件管理篇

宝塔面板教程之文件管理篇

宝塔面板其中一个最为便捷的功能之一,无需SFTP或者FTP即可对服务器的文件内容进行上传、下载、编辑及删除等管理操作。 文件管理,用于管理该服务器上的文件内容。 文件的基础操作 文件的基础操作有哪些了,主要有这些方面:复制、粘贴、剪切、删除、重命名、压缩、刷新、新建文件、新建目录。...

宝塔面板教程之计划任务篇

宝塔面板教程之计划任务篇

宝塔面板的计划任务,主要用于安排和管理需要定时执行的任务,如备份、内存清理等。其实对于大部分站长来说,主要使用该板块的备份网站、备份数据库及释放内存的三个定时任务计划。   Shell脚本的添加 输入任务名称,选择执行周期,输入执行的脚本内容。 注意事项: 输入脚本内容...

2022年Web开发人员的平均工资统计报告

2022年Web开发人员的平均工资统计报告

想成为一名网络开发人员或好奇工作的哪些子类型的薪水最高?Web开发是一个竞争激烈、多样化的行业,随着新语言和框架的出现而不断发展。 询问Web开发人员的薪水是一个难以解决的问题(尽管我们尝试)。有太多的因素需要考虑。 无论您是自由开发者还是有兴趣从事更传统的工作、喜欢前端或后端工作,或者想知...

如何成为一名出色的Java开发人员

如何成为一名出色的Java开发人员

美国劳工统计局估计在美有超过软件开发人员。根据2021年的数据,其中,这是世界上使用最广泛的五种编程语言之一。 自然,学习Java并成为Java开发人员对于任何对软件开发感兴趣的人来说都是明智的职业选择。 在本综合指南中,您将学习成为Java开发人员所需的一切知识。我们将分解您需要的技能、工...