函数返回值类型优化,JSX增强,TypeScript 5.1 发布!

dfb14eb443c42b6f5865fc0b53382032.gif

译者 | 禾木木       责编 | 夏萌

出品 | CSDN(ID:CSDNnews)

近日,微软宣布正式发布 TypeScript 5.1版本。

如果你还不熟悉 TypeScript,它是一种建立在 JavaScript 基础上的语言,通过添加静态类型语法来构建的语言。这些类型可以描述我们程序的一些细节,可以使用 TypeScript 对代码进行类型检查,并在运行代码之前告诉你代码错误的相关信息。

此外,你还可以使用 TypeScript 编译器从代码中剥离类型,并为你提供可在任何地方运行的简洁易读的 JavaScript 代码。除了类型检查之外,TypeScript 还使用静态类型来支持强大的编辑器工具,例如自动完成、代码导航、重构等。

如果你在 Visual Studio Code 或 Visual Studio 这样的编辑器中使用过 JavaScript,那么你已经用上了类型和 TypeScript 带来的体验。

如果你已经在项目中使用 TypeScript,则可以通过 NuGet 获取它,也可以通过以下命令使用 npm 获取:

npm install -D typescript

以下是 TypeScript 5.1 版本中新增的主要功能:

  • 更容易实现  undefined 函数的返回值类型

  • getter 和 setter 支持设置不同类型

  • JSX 元素和 JSX 标签类型之间解耦类型检查

  • 带命名空间的 JSX 标签

  • typeRoots在模块解析中被查询

  • JSX 标签支持链接光标

  • @Param JSDoc 标签中支持代码补全

  • 优化

  • 重大变更

61e4af99a6113d35606c3530dbeb6a76.png

Beta版本和RC版有哪些新变化?

Beta版以后,纠正了装饰器中init钩子的一些行为,并作出调整。还对 isolatedModules 下的 emit 行为进行了修改,以确保脚本文件不会被重写为模块。这也意味着使用 transpileModule API 不会将脚本文件被解释为模块,因为它假定使用了 isolatedModules。

RC版以后,对内置重构进行了轻微的迭代。但,实现仍然需要一些改进。因此,你现在可能无法在大多数编辑器中访问它,只能通过使用 TypeScript 的夜间版本来选择。预计 TypeScript 5.2 或 TypeScript 5.1 的未来补丁版本将重新引入这种重构。

2dbe01f689b98c1fc8efe70017e867c8.png

更容易实现 undefined 函数的返回值类型

在 JavaScript 中,如果函数在执行过程中没有返回值,就会返回 undefined:

function foo() {// no return
}// x = undefined
let x = foo();

然而,在以前版本的 TypeScript 中,只有返回值类型为 void 和 any 的函数可以没有 return语句。这意味着即使明确知道这个函数是返回 undefined 的,也需要至少有一个 return 语句。

// fine - we inferred that 'f1' returns 'void'
function f1() {// no returns
}// fine - 'void' doesn't need a return statement
function f2(): void {// no returns
}// fine - 'any' doesn't need a return statement
function f3(): any {// no returns
}// ❌ error!
// A function whose declared type is neither 'void' nor 'any' must return a value.
function f4(): undefined {// no returns
}

如果某个 API 希望函数返回 undefined。在以前的版本中,可能需要显式返回一个 undefined 或者显式添加一个 return 语句。

declare function takesFunction(f: () => undefined): undefined;// error! 
// Argument of type '() => void' is not assignable to parameter of type '() => undefined'.
takesFunction(() => {// no returns
});// error!
// A function whose declared type is neither 'void' nor 'any' must return a value.
takesFunction((): undefined => {// no returns
});// error!
// Argument of type '() => void' is not assignable to parameter of type '() => undefined'.
takesFunction(() => {return;
});// works
takesFunction(() => {return undefined;
});// works 
takesFunction((): undefined => {return;
});

这种行为令人困惑,尤其是在调用无法控制的函数时。理解推断 void 和 undefined 之间的相互作用,以及一个返回 undefined 的函数是否需要一个 return 语句等。

在 TypeScript 5.1 中,允许返回 undefined 的函数没有 return 语句。如下所示:

// worksfunction f4(): undefined { // no returns}// workstakesFunction((): undefined => { // no returns});

如果函数没有 return 并且被传递给期望返回 undefined 的函数参数,TypeScript 会推断该函数的返回类型为 undefined。

//  Works in TypeScript 5.1!takesFunction(function f() {    //                 ^ return type is undefined    // no returns});//  Works in TypeScript 5.1!takesFunction(function f() {    //                 ^ return type is undefined    return;});

为了解决另一个类似的痛点,在 TypeScript 的 --noImplicitReturns 选项下,仅返回 undefined 的函数现在具有与 void 类似的异常,因为并非每个代码路径都必须以显式 return 结束。

//  Works in TypeScript 5.1 under '--noImplicitReturns'!
function f(): undefined {if (Math.random()) {// do some stuff...return;}
}

0dc1c0c2456552ae4b0f98a9545f3772.png

getter和setter支持设置不同类型

TypeScript 4.3 使得 get 和 set 访问器对可以指定两种不同的类型成为可能。

interface Serializer {set value(v: string | number | boolean);get value(): string;
}declare let box: Serializer;// Allows writing a 'boolean'
box.value = true;// Comes out as a 'string'
console.log(box.value.toUpperCase());

‍最初要求 get 类型必须是 set 类型的子类型。意味着以下的代码是合理的:

box.value = box.value;

但是,有许多现有的和提议的 API 在它们的 getter 和 setter 之间具有完全不相关的类型。

TypeScript 5.1 现在允许 get 和 set 访问器属性设置不同的类型,前提是它们具有显式类型注释。虽然此版本的 TypeScript 尚未更改这些内置接口的类型,但现在可以通过以下方式定义:

interface CSSStyleRule {get style(): CSSStyleDeclaration;set style(newValue: string);
}

也允许其他模式的使用,但如果某些基础状态尚未初始化,则访问器可以返回。

class SafeBox {#value: string | undefined;// 只接受字符串set value(newValue: string) {}// 必须检查 undefinedget value(): string | undefined {return this.#value;}
}

实际上,这与在 --exactOptionalProperties 下检查可选属性的方式类似。

536e55f900ec6e132ff25232a721c436.png

JSX 元素和 JSX 标签类型之间解耦类型检查

TypeScript 在处理 JSX 时的一个痛点是对每个 JSX 元素标签类型的要求。而这个版本使得 JSX 库能够更准确地描述 JSX 组件的返回类型。对于很多人来说,这具体意味着可以在 React 中使用异步服务器组件。

例如,有以下 JSX 元素:

// A self-closing JSX tag
<Foo />// A regular element with an opening/closing tag
<Bar></Bar>

当对 <Foo />或<Bar></Bar> 进行类型检查时,TypeScript 总是会查找名为 JSX 的命名空间,并从中获取一个名为 Element 的类型,也就是在查找 JSX.Element。

但是,为了检查 Foo 或 Bar 本身是否是有效的标签名称,TypeScript 会粗略地获取由 Foo 或 Bar 返回或构造的类型,并检查与 JSX.Element 的兼容性(或者如果类型是可构造的,则检查另一种称为 JSX.ElementClass 的类型)。

这个限制意味着如果组件返回比 JSX.Element 更广泛的类型,则无法使用组件。

举一个具体的例子,React 的未来版本提议对返回 Promise 的组件提供有限支持,但是现有版本的TypeScript 无法表达这种类型,除非彻底放宽 JSX.Element 的类型限制。

import * as React from "react";async function Foo() {return <div></div>;
}
let element = <Foo />;
//             ~~~
// 'Foo' cannot be used as a JSX component.
//   Its return type 'Promise<Element>' is not a valid JSX element.

为了向库提供一种表达方式,TypeScript 5.1 现在会查找名为 JSX.ElementType 的类型。ElementType 精确指定什么可以有效用作 JSX 元素中的标签。因此,它可能会被定义为类似于以下这样:

namespace JSX {export type ElementType =// All the valid lowercase tagskeyof IntrinsicAttributes// Function components(props: any) => Element// Class componentsnew (props: any) => ElementClass;export interface IntrinsictAttributes extends /*...*/ {}export type Element = /*...*/;export type ClassElement = /*...*/;
}

fb1303c9c2844017dd995e25bca1c8b8.png

命名空间的 JSX 标签

在使用 JSX 时,可以使用带命名空间的属性名。

import * as React from "react";// Both of these are equivalent:
const x = <Foo a:b="hello" />;
const y = <Foo a : b="hello" />;interface FooProps {"a:b": string;
}function Foo(props: FooProps) {return <div>{props["a:b"]}</div>;
}

当名称的第一部分是小写字母时,JSX.IntrinsicAttributes 上的命名空间属性名会以类似的方式进行查找。

// In some library's code or in an augmentation of that library:
namespace JSX {interface IntrinsicElements {["a:b"]: { prop: string };}
}// In our code:
let x = <a:b prop="hello!" />;

65cb90b8c594a4794ee9e3c7461e2db4.png

typeRoots 在模块解析中被查询

当 TypeScript 指定的模块查找策略无法解析路径时,它现在将解析相对于指定 typeRoots 的包。

3af907ebdee1e613018d34d4e868e1d2.png

引入 JSX 标签中链接光标

TypeScript 现在支持 JSX 标签名称的链接编辑。允许编辑器自动同时编辑多个位置。

dbcaf43d424f05d38ef2e64b42544374.gif

这项新功能应该适用于 TypeScript 和 JavaScript 文件,并且可以在 Visual Studio Code Insiders 中启用。在 Visual Studio Code 中,勾选 Editor: Linked Editing 选项即可启用:

5446f02b5c0b18a732fcc9f3eac1ac1c.png

或者在 JSON 设置文件中配置 editor.linkedEditing:

{ // ... "editor.linkedEditing": true,}

Visual Studio 17.7 Preview 1 也将支持此功能。

3b4173b2d39b790c44b36a2e8bd96d14.png

@Param JSDoc 标签中支持代码补全

在 TypeScript 和 JavaScript 文件中输入 @param 标签时,TypeScript 现在提供代码补全。

4a31a45fcfdc12976161791a206feb49.gif

b4d8460128fb08a8438eaf5d2674b6df.png

优化

避免不必要的类型实例化

TypeScript 5.1 现在避免在已知不包含对外部类型参数的引用的对象类型中执行类型实例化。这有可能减少许多不必要的计算,并将 material-ui 的文档目录的类型检查时间减少 50% 以上。

通过减少不必要的类型实例化,TypeScript 5.1 在类型检查方面提供了更高的效率。尤其是在具有复杂类型层级或大型代码库的情况下,可以显著提高类型检查的性能。

联合字面量类型检查优化

在检查源类型是否属于联合类型时,TypeScript首先将使用该源类型的内部类型标识符进行快速查找。如果查找失败,则TypeScript会针对联合类型中的每种类型检查其兼容性。当将字面类型与仅包含字面类型的联合类型相关联时,TypeScript现在可以避免针对联合类型中的每种其他类型进行完整遍历。

这种优化可以将此问题中的代码的类型检查时间从约 45 秒减少到约 0.4 秒。

在解析JSDoc时,减少对扫描器的调用

在旧版本的 TypeScript 中,解析 JSDoc 注释时会使用扫描器/标记器将注释分解为细粒度的标记,并将内容重新组合。这在规范化注释文本方面可能是有帮助的,例如多个空格会被合并为一个空格,但这种方法会导致解析器和扫描器之间频繁的跳转,增加了 JSDoc 解析的开销。

TypeScript 5.1 对将 JSDoc 注释分解为扫描器/分词器中的内容更改了逻辑。扫描器现在将更大的内容块直接返回给解析器,以便根据需要进行处理。

这些更改已将几个 10Mb 的主要是注释的 JavaScript 文件的解析时间缩短了大约一半。

eed66758060fd8231587c6960fe85322.png

重大变更

ES2020 和 Node.js 14.17 作为最低运行时要求

TypeScript 5.1 现在包含了在 ECMAScript 2020 中引入的 JavaScript 功能。因此,TypeScript 至少需要在一个相对较新的运行时环境下运行。对于大多数用户来说,这意味着 TypeScript 现在只能在 Node.js 14.17 及更高版本上运行。

如果你尝试在较旧版本的 Node.js(如 Node 10 或 12)上运行 TypeScript 5.1,可能会遇到以下错误,无论是运行 tsc.js 还是 tsserver.js:

node_modules/typescript/lib/tsserver.js:2406 for (let i = startIndex ?? 0; i < array.length; i++) {                         ^SyntaxError: Unexpected token '?' at wrapSafe (internal/modules/cjs/loader.js:915:16) at Module._compile (internal/modules/cjs/loader.js:963:27) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12) at internal/main/run_main_module.js:17:47

此外,如果你尝试安装 TypeScript,你将会收到类似以下的错误信息:

npm WARN EBADENGINE Unsupported engine {npm WARN EBADENGINE package: 'typescript@5.1.3',npm WARN EBADENGINE required: { node: '>=14.17' },npm WARN EBADENGINE current: { node: 'v12.22.12', npm: '8.19.2' }npm WARN EBADENGINE }

来自 Yarn:

error typescript@5.1.3: The engine "node" is incompatible with this module. Expected version ">=14.17". Got "12.22.12"error Found incompatible module.

显式指定了 typeRoots 后,将禁用对 node_modules/@types 的向上查找

以前,在 tsconfig.json 中指定了 typeRoots 选项但无法解析到任何 typeRoots 目录时,TypeScript 仍然会继续向上遍历父目录,尝试在每个父目录的 node_modules/@types 文件夹中解析包。

这种行为可能导致过多的查找,并且在 TypeScript 5.1 中已被禁用。因此,您可能会开始看到类似以下错误的错误,这是基于您的 tsconfig.json 中的 types 选项或 /// 指令的条目而产生的:

error TS2688: Cannot find type definition file for 'node'.error TS2688: Cannot find type definition file for 'mocha'.error TS2688: Cannot find type definition file for 'jasmine'.error TS2688: Cannot find type definition file for 'chai-http'.error TS2688: Cannot find type definition file for 'webpack-env"'.

解决方案通常是在您的 typeRoots 中添加针对 node_modules/@types 的特定条目:

{"compilerOptions": {"types": ["node","mocha"],"typeRoots": [// Keep whatever you had around before."./some-custom-types/",// You might need your local 'node_modules/@types'."./node_modules/@types",// You might also need to specify a shared 'node_modules/@types'// if you're using a "monorepo" layout."../../node_modules/@types",]}
}

以上就是 TypeScript 5.1 的稳定版本所更新的内容,此外,微软项目团队已经在努力开发 TypeScript 5.2 版本,如果你想知道更多关于 TypeScript 5.1 版本的信息,可查看发布说明。

参考链接:

https://devblogs.microsoft.com/typescript/announcing-typescript-5-1/

推荐阅读:

▶腾讯回应考生喊话马化腾;库克承认在使用 ChatGPT;OpenHarmony 4.0 Beta1 发布|极客头条

▶算网共生 云智无界 | 算网的新征程等你加入

▶AI 大战高考作文!实测 ChatGPT、文心一言、通义千问等 8 款“神器”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/68076.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用 GPT-4 创建 VSCode 插件,我遇到的六个问题!

让 GPT-4 从头开发一个扩展&#xff0c;会有什么情况发生&#xff1f;它的代码真的可以安装、编译、运行吗&#xff1f;一位开发者 KEVIN LIN 进行了一次测试。 原文链接&#xff1a;https://bit.kevinslin.com/p/leveraging-gpt-4-to-automate-the 声明&#xff1a;本文为 CSD…

什么是长尾关键词?如何找到长尾关键词?以及使用长尾词的九大理由

长尾关键词 文章目录 长尾关键词前言一、长尾理论二、什么是长尾关键词?三、如何找到长尾关键词?四、在SEO中使用长尾关键字的9个理由1.长尾会带来大量流量。2.长尾关键词已经包含头部关键词。3.长尾巴带来更好的针对性流量。4.长尾提高转换率。5.长尾查询非常适合PPC。6.长尾…

AI生成的东西越来越真实,你该如何分辨

ChatGPT的出现&#xff0c;改变很多职场人士的工作习惯&#xff0c;同样在学校里的中学生、大学生写作业、论文的方式也在进行极大的改变&#xff0c;有些学校甚至禁止使用ChatGPT&#xff0c;因为长此以往会导致学生的思考和创造能力下降&#xff0c;以及对学科知识的理解能力…

如何通过网关降低大模型的调用费用,并提升合规性

作者&#xff1a;赵伟基(兆维) 以 ChatGPT 为代表的 AIGC 技术为企业生产带来了巨大的变化&#xff0c;并在企业应用开发领域占据一席之地。AI 大模型凭借其强大的学习能力&#xff0c;可以帮助人们完成各种复杂的任务&#xff0c;例如帮助开发人员编写与调试代码、研究人员快…

ChatGPT:你才是编译器!你全家都是编译器!

我是不是再也不需要编译器了&#xff1f;&#xff01; 这个故事的灵感来自一个类似的文章&#xff1a;在 ChatGPT 中构建虚拟机。我印象深刻并决定尝试类似的东西&#xff0c;但这次不是 Linux 命令行工具&#xff0c;而是让 ChatGPT 成为我们的 Python 编译器。 这是初始化 Ch…

chatgpt赋能python:Python中文输入指南

Python 中文输入指南 Python 作为一门广泛应用于编程领域的高级语言&#xff0c;实现了许多优秀的工具和库来支持中文输入。本文将介绍 Python 如何输入中文以及一些常见的工具和方法。 为什么 Python 输入中文很重要&#xff1f; 随着人们对中文的不断重视&#xff0c;相应…

GitHub Copilot:让开发编程变得像说话一样简单

引用&#xff1a; 人类天生就梦想、创造、创新。但今天&#xff0c;我们花太多时间被繁重的工作所消耗&#xff0c;花在消耗我们时间、创造力和精力的任务上。为了重新连接我们工作的灵魂&#xff0c;我们不仅需要一种更好的方式来做同样的事情&#xff0c;更需要一种全新的工…

php茶餐厅销售管理系统的设计与实现

本系统将运用phpstudy开发工具构件开发环境&#xff1b;基于PHP&#xff0c;用HTMLCSS来设计界面&#xff0c;用oracle作为数据库与PHP搭建来存储数据信息&#xff1b;最终以HTMLCSSJSPPHPoracle来实现本系统的所有开发。所以&#xff0c;在设计上是尽量涉及到和茶餐厅相关的销…

餐饮外卖销售系统数据库设计

简介 ​ 对于人工数据管理系统&#xff0c;存在许多的弊端&#xff0c;手工录入、耗费人力、工作繁琐&#xff0c;准确性也无法保证&#xff0c;并且相当耗费时间&#xff0c;对于数据量巨大的餐饮外卖销售系统来说&#xff0c;人工数据管理系统已经无法满足其需求。本次设计的…

餐饮营销策划案例合集(共18份)

合集名称&#xff1a;餐饮营销策划案例合集 数量&#xff1a;共18份 具体内容&#xff1a; 【餐饮策划案例】2021下厨房年营销通案.pdf【餐饮策划案例】2021美团点评APP品牌营销通案.pdf【餐饮策划案例】2021肥汁米蘭港式米线品牌手册.pdf【餐饮策划案例】2021金领大厨超级小…

数据分析:餐厅订单数据分析

数据分析&#xff1a;餐厅订单数据分析 作者&#xff1a;i阿极 作者简介&#xff1a;Python领域新星作者、多项比赛获奖者&#xff1a;博主个人首页 &#x1f60a;&#x1f60a;&#x1f60a;如果觉得文章不错或能帮助到你学习&#xff0c;可以点赞&#x1f44d;收藏&#x1f4…

浏览器控制台命令指南-重制版

提示&#xff1a;本文重制版&#xff0c;重制版&#xff0c; 文章目录 前言一、控制台.log命令二、第一步.clear命令1.clear2.更多~设置输出样式assert()count()dir() and dirxml()group&#xff08;&#xff09;&#xff0c;groupCollapsed&#xff08;&#xff09;和groupEnd…

chatgpt赋能python:Python操作网页的SEO

Python操作网页的SEO 在当今的数字时代&#xff0c;许多企业专注于提高其网站的排名。在这种竞争激烈的环境中&#xff0c;搜索引擎优化&#xff08;SEO&#xff09;是必不可少的。虽然有许多方法可以提高网站的排名&#xff0c;但其中一个最重要的是使用Python来操作网页。 …

商标名字一样,图标不一样属于商标侵权吗?

如果产品的商标名字不一样&#xff0c;但图标相似算商标侵权吗? 这个问题涉及到商标侵权行为的认定&#xff0c;在商标法的规定中&#xff0c;为了保护注册商标的合法权益&#xff0c;对商标权侵权行为的认定做了较为具体的解释&#xff0c;我们可以以此作为“商标名字一样图…

如何设计商标图案?

如何设计商标图案是企业经营者需要考虑的一个问题&#xff0c;商标的形象是企业的形象&#xff0c;而企业的形象直接影响着消费者对产品的看法。因此&#xff0c;设计好商标图案是非常重要的。下面小编就来给大家介绍一下&#xff1a;如何设计商标图案。 如何设计商标图案? 一…

新表情将至?腾讯申请新狗头图形商标

IT之家 10 月 9 日消息&#xff0c;腾讯科技 &#xff08;深圳&#xff09; 有限公司近日申请注册多个狗头形象图形商标以及“微信创意表情”商标&#xff0c;国际分类含广告销售、教育娱乐、通讯服务等&#xff0c;当前商标状态均为注册申请中。 近年来&#xff0c;微信、微博…

天猫精灵使用体验之一——天猫精灵初体验

在前面,小智已经介绍过,天猫精灵是小智在2017年双11下单的,等了一个多月,12月下旬才收到货。所以当天猫精灵从盒子里面蹦出来到体验官面前时,体验官就迫不可待地开始了一列表的体验和测评——什么开箱照、什么全家福的通通都没有,有的都是经过一个多月体验和测评后总结出…

揭秘!一文读懂数据策略在模型训练中的重要意义

编者按&#xff1a; 我们知道&#xff0c;当有了一个基础模型之后&#xff0c;可从两个维度来提高它的性能&#xff0c;一是以模型为中心的方法&#xff0c;即想尽各种办法提高算法设计的复杂度、技术含量等&#xff1b;二是以数据为中心的方法&#xff0c;通过数据增强、合成数…

AIGX 智生万物 | 浦软创业营(第九期)人工智能专场,正式开启招募!

"GPT 是我一生中见到的两项最具革命性技术之一。" ——Bill Gates"我认为ChatGPT引发的AI浪潮&#xff0c;在规模上与工业革命、电力、甚至是轮子的发明相当。" ——Geoffrey Hinton"关于人工智能未来十年的前景&#xff0c;我们有一系列很重要的经验…

一键生成伪原创文章有用吗(正确使用伪原创工具)

一定有不少的SEOer正在使用伪原创文件生成器这个工具吧&#xff0c;我可以正确的断定出来&#xff0c;一个懂SEO优化的SEOer绝对能够正确理解文章的作用&#xff0c;而那些似懂非懂的SEOer每天都在为原创文章的事情烦恼。往往一直以为每天坚持更新文章就可以获得排名的SEOer却没…