竹笋

首页 » 问答 » 环境 » TypeScript36新功能尝鲜学习
TUhjnbcbe - 2023/2/15 9:33:00
白癜风治疗微信群 http://nvrenjkw.com/nxzx/5717.html

上周微软Devblog宣布发布TypeScript3.6。

TypeScript是delphi之父、.net之父,c#之父世界著名程序员爱德斯.海尔斯伯格领导开发、微软免费开源的一种替代JavaScript的语言。它通过添加静态类型,用增强编译编译时错误捕捉。其强大的编译器和Babel等工具套件可以将优雅编写的TypeScript代码转换为标准的ECMAScriptJS代码,支持在JS运行环境下,比如任何浏览器运行。

TypeScript不光语法优雅还支持大量的编辑器和IDE工具,可以在众多的编辑器实现代码完成,重构和快速修复等功能提供支持。当然最好的还是微软系的VS和VSC。

TypeScript生态圈也相当完善,比如著名的前端框架Angular,Angular2就完全用TypeScript完全重写。

说了这多TypeScript的介绍,现在进入主题介绍TypeScript3.6的新功能。

更严格生成器

TypeScript3.6引入了对迭代器和生成器函数的更严格的检查。早期版本中,生成器用户无法区分是否从生成器生成或返回值。

此外,生成器总会假设yield类型为any。

TypeScript3.6中,检查器现在知道curr.value的正确类型应该是我们的第一个示例中的字符串,上一个示例中调用next()时会报错。由于新版本中Iterator和IteratorResult类型声明中增强,引入了一些新的类型参数,还新增加了一个Generator类型的生成器。

Iterator类型可以支持用户指定生成的类型,返回的类型以及next可接受的类型。

新的Generator类型是一个迭代器,它同时存在return和throw方法,并且也是可迭代的。

为了区分返回值和结果,TypeScript3.6将IteratorResult类型转换为区分联合类型:

在直接处理迭代器时,我们可以适当地缩小迭代器的值。

为了正确表示可以调用next()传递给生成器的类型,TypeScript3.6还支持在生成器函数体内推断出yield的某些用法。

也可以使用显式返回类型强制执行可以从yield表达式返回,生成和计算的值类型。下面示例中,next()只能用布尔值调用,并且根据done的值,value可以是字符串或数字。

结果为:0-9,Done

更准确的数组转换

在ES之前的目标中,对于for和of循环和数组扩展之类的结构说实话有点重。为此TypeScript默认使用更简单的emit,它只支持数组类型,并支持使用--downlevelIteration标志对其他类型迭代。通过此标志,emit代码更准确,但更大。

默认情况下—downlevelIteration被设置为关闭,效果很好,大多数以ES5为目标的用户一般都只会使用数组的迭代。但是,只支持数组的emit在某些边缘情况下也有差异。

比如以下示例:

[...Array(5)]

相当于以下数组。

[未定义,未定义,未定义,未定义,未定义]

但是,TypeScript会将原始代码转换为代码:

Array(5).slice();

这略有不同。Array(5)会生成一个长度为5的数组,是成员未定义属性

1in[undefined,undefined,undefined]//true

1inarray(3)//false

当TypeScript调用slice()时,它还会创建一个尚未设置索引的数组。

TypeScript3.6中午没有使用slice()和内置函数,而是引入了一个新的__spreadArrays辅助程序,可以准确地模拟ECMAScript中--downlevelIteration之外的对象发生的行为。--downlevelIteration.__spreadArrays也可以在tslib中使用。

改进UXPromise

Promise是时下最常用的数据异步方法之一。但是面向Promise的API通常会让用户感到困惑。TypeScript3.6引入了一些改进,以防止Promise的误用。

例如,在将Promise传递给另一个函数之前通常会忘记.then()或await。TypeScript的错误消息现在会明确的告知用户应该考虑使用await关键字。

//~~~~~~~~~~~~~

//ArgumentoftypePromiseUserisnotassignabletoparameteroftypeUser.

//...

//Didyouforgettouseawait?

在await或.then()前试图访问方法也很常见。下面是另一个错误的示例:

即使用户不知道await,这些消息提供了更多相关的信息。

除了Promises上更好的错误消息提示以外,新版本还在某些情况下提供快速修复。

更好的Unicode支持

当转换到ES及更高版本时,TypeScript3.6在标识符中提供对Unicode字符的更好支持。

const=world;//以前不允许,现在支持--targetes

system.JS中的import.meta支持

当模块转化目标设置为system时,TypeScript3.6支持将import.meta转换为context.meta。

在环境上下文中允许get和set操作符

在以前的TypeScript版本中,不允许在环境上下文中使用get和set操作符(例如在declare-d类中,或在.d.ts文件中)。理由是,就这些属性的读写而言,操作符与属性没有区别。ECMAScript的类字段提议可能与现有的TypeScript版本有不同的行为,所以需要一种方法来传达这种不同的行为。

为此TypeScript3.6中,支持用户可以环境上下文中编写getter和setter。

declareclassFoo{

//TS3.6+允许:

getx():number;

setx(val:number):void;

}

在随后的TypeScript3.7中编译器本身将利用此功能以便生成的.d.ts文件也支持get/set操作符。

环境类和函数可以合并

此前TypeScript在任何情况下合并类和函数都是错误的。现在,环境类和函数(具有declare修饰符的类/函数或.d.ts文件中的)可以合并。在新版本中下面代码是ok的:

对比,之前需要这样写:

新版本写法的优点是可以很容易地表达可调用的构造函数模式,同时还允许名称空间与这些声明合并。

在下一个版本TypeScript3.7中,编译器将利用此功能从.js文件生成的.d.ts文件可以适当地捕获这些类似类的函数的可调用性和可构造性。

API对--build和—incremental的支持

TypeScript3.0引入了对引用其他项目的支持,并使用--build标志以增量方式构建它们。此外,TypeScript3.4引入了--incremental标志,用于保存有关历史编译的信息,仅重建某些文件。这些标志对于更灵活地构建项目和加速构建非常有用。但是,这些标志不适用于Gulp和Webpack等第三方构建工具。TypeScript3.6版本公开了两组API操作项目引用和增量程序构建。

对于--incremental构建,用户可以利用createIncrementalProgram和createIncrementalCompilerHostAPI。用户还可以使用新公开的readBuilderProgram函数用此API生成的.tsbuildinfo文件中重新保存旧程序实例,该函数仅用于创建新程序(无法修改返回的实例,只用于其他create*Program函数中的oldProgram参数)。

为了利用项目引用,公开了一个新的createSolutionBuilder函数,它返回一个新类型SolutionBuilder的实例。

新的TypeScriptPlayground

TypeScriptPlayground新支持许多新选项,包括:

目标选项(允许用户从es5切换到es3,es,esnext等)

所有严格标志(包括strict)

支持纯JavaScript文件(使用allowJS和可选的checkJs)

智能分号感知

VisualStudio和VisualStudioCode等编辑器可以自动应用快速修复,重构和其他转换,例如自动从其他模块导入值。这些转换由TypeScript提供支持,旧版本的TypeScript会无条件地在每个语句的末尾添加分号。但是该行为可能不符合一些用户的风格指南,许多用户对编辑器自动插入分号感到不满。

TypeScript新版本提供足够智能,可以在应用自动添加时检测的文件是否使用了分号。如果文件通常缺少分号,则TypeScript不会自动添加分号。

更智能的自动Import

JavaScript有很多不同的模块语法或约定:ECMAScript标准;Node(CommonJS);AMD,System.js等等。在大多数情况下,TypeScript默认使用ECMAScript模块语法自动导入,这在某些具有不同编译器设置TypeScript项目中通常是不合适的,也不适用于在纯JavaScript和需要调用的Node项目中。

TypeScript3.6现在更加智能地对比现有导入,然后进行自动导入。

突破性变化

命名为constructor的类成员为构造函数

根据ECMAScript规范,使用名为constructor的方法的类声明是构造函数,无论它们是使用标识符名称还是字符串名称声明。

classC{

constructor(){

console.log(Iamtheconstructornow.);

}

}

唯一例外的是在计算属性中使用:

classD{

[constructor](){

console.log(Imnotaconstructor-justaplainmethod!);

}

}

DOM更新

许多声明已在lib.dom.d.ts中删除或更改。这包括(但不限于)以下内容:

全局窗口不再定义为类型Window,而是将其定义为类型WindowtypeofglobalThis。在某些情况下,最好将其类型称为窗口类型;

GlobalFetch用WindowOrWorkerGlobalScope取代;

导航器上的某些非标准属性消失了;

experimental-webgl被webgl或webgl2取代;

如果您认为有错误的更改,请提出问题!

JSDoc注释不再合并

在JavaScript文件中,TypeScript只会在JSDoc注释之前立即查询以确定声明的类型。

/**

*

param{string}arg

*/

/**

*oh,hi,wereyoutryingtotypesomething?

*/

functionwhoWritesFunctionsLikeThis(arg){

//arghastypeany

}

关键字不能包含转义字符

此前关键字允许包含转义字符。TypeScript3.6将不再支持。

while(true){

\uontinue;

}

//~~~~~~~~~~~~~

//error!Keywordscannotcontainescapecharacters.

下载安装

可以通过NuGet获取它,或使用npm命令下载安装:

npminstall-gtypescript

更多文档和帮助请浏览typescript

1
查看完整版本: TypeScript36新功能尝鲜学习