从 node_modules
开始支持 lib
¥Supporting lib
from node_modules
为了确保 TypeScript 和 JavaScript 支持开箱即用,TypeScript 打包了一系列声明文件(.d.ts
文件)。这些声明文件代表了 JavaScript 语言中可用的 API 以及标准浏览器 DOM API。虽然根据你的 target
有一些合理的默认值,但你可以通过在 tsconfig.json
中配置 lib
设置来选择程序使用的声明文件。
¥To ensure that TypeScript and JavaScript support works well out of the box, TypeScript bundles a series of declaration files (.d.ts
files).
These declaration files represent the available APIs in the JavaScript language, and the standard browser DOM APIs.
While there are some reasonable defaults based on your target
, you can pick and choose which declaration files your program uses by configuring the lib
setting in the tsconfig.json
.
不过,在 TypeScript 中包含这些声明文件偶尔会有两个缺点:
¥There are two occasional downsides to including these declaration files with TypeScript though:
-
升级 TypeScript 时,你还必须处理 TypeScript 内置声明文件的更改,而当 DOM API 频繁更改时,这可能是一个挑战。
¥When you upgrade TypeScript, you’re also forced to handle changes to TypeScript’s built-in declaration files, and this can be a challenge when the DOM APIs change as frequently as they do.
-
很难根据项目依赖的需求定制这些文件(例如,如果你的依赖声明使用 DOM API,你可能也会被迫使用 DOM API)。
¥It is hard to customize these files to match your needs with the needs of your project’s dependencies (e.g. if your dependencies declare that they use the DOM APIs, you might also be forced into using the DOM APIs).
TypeScript 4.5 引入了一种覆盖特定内置 lib
的方法,其工作方式类似于 @types/
支持的工作方式。当决定 TypeScript 应该包含哪些 lib
文件时,它会首先在 node_modules
中查找作用域内的 @typescript/lib-*
包。例如,当在 lib
中包含 dom
作为选项时,TypeScript 将使用 node_modules/@typescript/lib-dom
中的类型(如果可用)。
¥TypeScript 4.5 introduces a way to override a specific built-in lib
in a manner similar to how @types/
support works.
When deciding which lib
files TypeScript should include, it will first look for a scoped @typescript/lib-*
package in node_modules
.
For example, when including dom
as an option in lib
, TypeScript will use the types in node_modules/@typescript/lib-dom
if available.
然后,你可以使用包管理器安装特定的包来接管给定的 lib
。例如,今天 TypeScript 在 @types/web
上发布了 DOM API 的版本。如果你想将项目锁定到特定版本的 DOM API,可以将以下内容添加到你的 package.json
中:
¥You can then use your package manager to install a specific package to take over for a given lib
For example, today TypeScript publishes versions of the DOM APIs on @types/web
.
If you wanted to lock your project to a specific version of the DOM APIs, you could add this to your package.json
:
json
{"dependencies": {"@typescript/lib-dom": "npm:@types/web"}}
然后从 4.5 开始,你可以更新 TypeScript,依赖管理器的锁文件将确保它使用完全相同版本的 DOM 类型。这意味着你可以根据自己的情况更新类型。
¥Then from 4.5 onwards, you can update TypeScript and your dependency manager’s lockfile will ensure that it uses the exact same version of the DOM types. That means you get to update your types on your own terms.
我们要特别感谢 saschanaz,在我们构建和试验此功能的过程中,他给予了我们极大的帮助和耐心。
¥We’d like to give a shout-out to saschanaz who has been extremely helpful and patient as we’ve been building out and experimenting with this feature.
更多信息,你可以查看 查看此变更的实现。
¥For more information, you can see the implementation of this change.
Awaited
类型和 Promise
改进
¥The Awaited
Type and Promise
Improvements
TypeScript 4.5 引入了一种名为 Awaited
类型的新工具类型。此类型旨在对 async
函数中的 await
或 Promise
中的 .then()
方法等操作进行建模 - 具体来说,他们递归地解开 Promise
的方式。
¥TypeScript 4.5 introduces a new utility type called the Awaited
type.
This type is meant to model operations like await
in async
functions, or the .then()
method on Promise
s - specifically, the way that they recursively unwrap Promise
s.
ts
// A = stringtype A = Awaited<Promise<string>>;// B = numbertype B = Awaited<Promise<Promise<number>>>;// C = boolean | numbertype C = Awaited<boolean | Promise<number>>;
Awaited
类型有助于对现有 API 进行建模,包括 JavaScript 内置函数,例如 Promise.all
、Promise.race
等。事实上,Promise.all
推断过程中遇到的一些问题正是 Awaited
的动机。以下是在 TypeScript 4.4 及更早版本中失败的示例。
¥The Awaited
type can be helpful for modeling existing APIs, including JavaScript built-ins like Promise.all
, Promise.race
, etc.
In fact, some of the problems around inference with Promise.all
served as motivations for Awaited
.
Here’s an example that fails in TypeScript 4.4 and earlier.
ts
declare function MaybePromise<T>(value: T): T | Promise<T> | PromiseLike<T>;async function doSomething(): Promise<[number, number]> {const result = await Promise.all([MaybePromise(100), MaybePromise(200)]);// Error!//// [number | Promise<100>, number | Promise<200>]//// is not assignable to type//// [number, number]return result;}
现在,Promise.all
利用某些特性与 Awaited
的组合来提供更好的推断结果,并且上述示例有效。
¥Now Promise.all
leverages the combination of certain features with Awaited
to give much better inference results, and the above example works.
更多信息,你可以查看 可以在 GitHub 上阅读有关此更改的信息。
¥For more information, you can read about this change on GitHub.
模板字符串类型作为判别式
¥Template String Types as Discriminants
TypeScript 4.5 现在可以缩小具有模板字符串类型的值的范围,并且还可以将模板字符串类型识别为判别式。
¥TypeScript 4.5 now can narrow values that have template string types, and also recognizes template string types as discriminants.
例如,下面的代码片段过去会失败,但现在在 TypeScript 4.5 中可以成功进行类型检查。
¥As an example, the following used to fail, but now successfully type-checks in TypeScript 4.5.
tsTry
export interfaceSuccess {type : `${string}Success`;body : string;}export interfaceError {type : `${string}Error`;message : string}export functionhandler (r :Success |Error ) {if (r .type === "HttpSuccess") {consttoken =r .body ;}}
更多信息请见 查看启用此功能的变更!
¥For more information, see the change that enables this feature.
module es2022
得益于 Kagami S.Rosylight,TypeScript 现在支持新的 module
设置:es2022
。module es2022
的主要特性是顶层 await
,这意味着你可以在 async
函数之外使用 await
。这在 --module esnext
(现在是 --module nodenext
)中已经得到支持,但 es2022
是该功能的第一个稳定目标。
¥Thanks to Kagami S. Rosylight, TypeScript now supports a new module
setting: es2022
.
The main feature in module es2022
is top-level await
, meaning you can use await
outside of async
functions.
This was already supported in --module esnext
(and now --module nodenext
), but es2022
is the first stable target for this feature.
你可以 在此处阅读更多有关此变更的信息。
¥You can read up more on this change here.
条件类型的尾递归消除
¥Tail-Recursion Elimination on Conditional Types
当 TypeScript 检测到可能的无限递归或任何可能需要很长时间并影响编辑器体验的类型扩展时,它通常需要优雅地失败。因此,TypeScript 具有启发式算法,以确保在尝试拆分无限深的类型或处理生成大量中间结果的类型时不会出错。
¥TypeScript often needs to gracefully fail when it detects possibly infinite recursion, or any type expansions that can take a long time and affect your editor experience. As a result, TypeScript has heuristics to make sure it doesn’t go off the rails when trying to pick apart an infinitely-deep type, or working with types that generate a lot of intermediate results.
ts
type InfiniteBox<T> = { item: InfiniteBox<T> };type Unpack<T> = T extends { item: infer U } ? Unpack<U> : T;// error: Type instantiation is excessively deep and possibly infinite.type Test = Unpack<InfiniteBox<number>>;
上面的例子故意设计得简单且无用,但实际上有很多类型很有用,不幸的是,它们会触发我们的启发式算法。例如,以下 TrimLeft
类型会从字符串类型的开头删除空格。如果给定一个开头带有空格的字符串类型,它会立即将字符串的其余部分返回到 TrimLeft
文件。
¥The above example is intentionally simple and useless, but there are plenty of types that are actually useful, and unfortunately trigger our heuristics.
As an example, the following TrimLeft
type removes spaces from the beginning of a string-like type.
If given a string type that has a space at the beginning, it immediately feeds the remainder of the string back into TrimLeft
.
ts
type TrimLeft<T extends string> =T extends ` ${infer Rest}` ? TrimLeft<Rest> : T;// Test = "hello" | "world"type Test = TrimLeft<" hello" | " world">;
此类型很有用,但如果字符串的前导空格数为 50,则会出错。
¥This type can be useful, but if a string has 50 leading spaces, you’ll get an error.
ts
type TrimLeft<T extends string> =T extends ` ${infer Rest}` ? TrimLeft<Rest> : T;// error: Type instantiation is excessively deep and possibly infinite.type Test = TrimLeft<" oops">;
这很遗憾,因为这些类型在对字符串进行建模操作时往往非常有用。 - 例如,URL 路由的解析器。更糟糕的是,更有用的类型通常会创建更多的类型实例,从而对输入长度有更大的限制。
¥That’s unfortunate, because these kinds of types tend to be extremely useful in modeling operations on strings - for example, parsers for URL routers. To make matters worse, a more useful type typically creates more type instantiations, and in turn has even more limitations on input length.
但是还有一个优点:TrimLeft
的编写方式是单分支尾递归。当它再次调用自身时,它会立即返回结果,而不会对其进行任何处理。因为这些类型不需要创建任何中间结果,所以它们可以更快地实现,并且避免触发 TypeScript 内置的许多类型递归启发式算法。
¥But there’s a saving grace: TrimLeft
is written in a way that is tail-recursive in one branch.
When it calls itself again, it immediately returns the result and doesn’t do anything with it.
Because these types don’t need to create any intermediate results, they can be implemented more quickly and in a way that avoids triggering many of type recursion heuristics that are built into TypeScript.
这就是为什么 TypeScript 4.5 对条件类型执行了一些尾递归消除。只要条件类型的一个分支仅仅是另一个条件类型,TypeScript 就可以避免中间实例化。仍然有一些启发式方法可以确保这些类型不会偏离轨道,但它们更加宽容。
¥That’s why TypeScript 4.5 performs some tail-recursion elimination on conditional types. As long as one branch of a conditional type is simply another conditional type, TypeScript can avoid intermediate instantiations. There are still heuristics to ensure that these types don’t go off the rails, but they are much more generous.
请记住,以下类型不会被优化,因为它通过将条件类型的结果添加到联合体中来使用它。
¥Keep in mind, the following type won’t be optimized, since it uses the result of a conditional type by adding it to a union.
ts
type GetChars<S> =S extends `${infer Char}${infer Rest}` ? Char | GetChars<Rest> : never;
如果你想使其尾递归,可以引入一个接受 “accumulator” 类型参数的辅助函数,就像尾递归函数一样。
¥If you would like to make it tail-recursive, you can introduce a helper that takes an “accumulator” type parameter, just like with tail-recursive functions.
ts
type GetChars<S> = GetCharsHelper<S, never>;type GetCharsHelper<S, Acc> =S extends `${infer Char}${infer Rest}` ? GetCharsHelper<Rest, Char | Acc> : Acc;
你可以阅读有关实现 此处 的更多信息。
¥You can read up more on the implementation here.
禁用导入省略
¥Disabling Import Elision
在某些情况下,TypeScript 无法检测到你正在使用导入。例如,采用以下代码:
¥There are some cases where TypeScript can’t detect that you’re using an import. For example, take the following code:
ts
import { Animal } from "./animal.js";eval("console.log(new Animal().isDangerous())");
默认情况下,TypeScript 总是会删除此导入,因为它似乎未被使用。在 TypeScript 4.5 中,你可以启用一个名为 preserveValueImports
的新标志,以防止 TypeScript 从 JavaScript 输出中删除任何导入的值。使用 eval
的充分理由很少,但在 Svelte 中也发生了类似的事情:
¥By default, TypeScript always removes this import because it appears to be unused.
In TypeScript 4.5, you can enable a new flag called preserveValueImports
to prevent TypeScript from stripping out any imported values from your JavaScript outputs.
Good reasons to use eval
are few and far between, but something very similar to this happens in Svelte:
html
<!-- A .svelte File --><script>import { someFunc } from "./some-module.js";</script><button on:click="{someFunc}">Click me!</button>
以及在 Vue.js 中使用其 <script setup>
功能:
¥along with in Vue.js, using its <script setup>
feature:
html
<!-- A .vue File --><script setup>import { someFunc } from "./some-module.js";</script><button @click="someFunc">Click me!</button>
这些框架会根据其 <script>
标签之外的标记生成一些代码,但 TypeScript 只会识别 <script>
标签内的代码。这意味着 TypeScript 将自动删除 someFunc
的导入,并且上面的代码将无法运行!在 TypeScript 4.5 中,你可以使用 preserveValueImports
来避免这些情况。
¥These frameworks generate some code based on markup outside of their <script>
tags, but TypeScript only sees code within the <script>
tags.
That means TypeScript will automatically drop the import of someFunc
, and the above code won’t be runnable!
With TypeScript 4.5, you can use preserveValueImports
to avoid these situations.
请注意,此标志与 —isolatedModules` 结合使用时有一个特殊要求:导入的类型必须标记为仅类型,因为一次处理单个文件的编译器无法知道导入是未使用的值,还是必须删除以避免运行时崩溃的类型。
¥Note that this flag has a special requirement when combined with —isolatedModules`: imported types must be marked as type-only because compilers that process single files at a time have no way of knowing whether imports are values that appear unused, or a type that must be removed in order to avoid a runtime crash.
ts
// Which of these is a value that should be preserved? tsc knows, but `ts.transpileModule`,// ts-loader, esbuild, etc. don't, so `isolatedModules` gives an error.import { someFunc, BaseType } from "./some-module.js";// ^^^^^^^^// Error: 'BaseType' is a type and must be imported using a type-only import// when 'preserveValueImports' and 'isolatedModules' are both enabled.
这使得 TypeScript 4.5 的另一个功能 type
导入名称上的修饰符 尤为重要。
¥That makes another TypeScript 4.5 feature, type
modifiers on import names, especially important.
更多信息请见 查看此处的拉取请求!
¥For more information, see the pull request here.
type
导入名称的修饰符
¥type
Modifiers on Import Names
如上所述,preserveValueImports
和 isolatedModules
有特殊要求,因此构建工具不会对是否可以安全地删除类型导入产生歧义。
¥As mentioned above, preserveValueImports
and isolatedModules
have special requirements so that there’s no ambiguity for build tools whether it’s safe to drop type imports.
ts
// Which of these is a value that should be preserved? tsc knows, but `ts.transpileModule`,// ts-loader, esbuild, etc. don't, so `isolatedModules` issues an error.import { someFunc, BaseType } from "./some-module.js";// ^^^^^^^^// Error: 'BaseType' is a type and must be imported using a type-only import// when 'preserveValueImports' and 'isolatedModules' are both enabled.
当这些选项组合在一起时,我们需要一种方法来指示何时可以合法地删除导入。TypeScript 已经通过 import type
实现了此目的:
¥When these options are combined, we need a way to signal when an import can be legitimately dropped.
TypeScript already has something for this with import type
:
ts
import type { BaseType } from "./some-module.js";import { someFunc } from "./some-module.js";export class Thing implements BaseType {// ...}
这可行,但最好避免对同一模块使用两个 import 语句。这就是为什么 TypeScript 4.5 允许在单个命名导入上使用 type
修饰符的原因之一,这样你就可以根据需要进行混合搭配。
¥This works, but it would be nice to avoid two import statements for the same module.
That’s part of why TypeScript 4.5 allows a type
modifier on individual named imports, so that you can mix and match as needed.
ts
import { someFunc, type BaseType } from "./some-module.js";export class Thing implements BaseType {someMethod() {someFunc();}}
在上面的例子中,BaseType
始终保证被删除,而 someFunc
将保留在 preserveValueImports
下,因此我们得到以下代码:
¥In the above example, BaseType
is always guaranteed to be erased and someFunc
will be preserved under preserveValueImports
, leaving us with the following code:
js
import { someFunc } from "./some-module.js";export class Thing {someMethod() {someFunc();}}
更多信息,请参阅 GitHub 上的更改。
¥For more information, see the changes on GitHub.
私有字段存在性检查
¥Private Field Presence Checks
TypeScript 4.5 支持 ECMAScript 提案,用于检查对象是否具有私有字段。现在,你可以编写一个包含 #private
字段成员的类,并使用 in
运算符查看另一个对象是否具有相同的字段。
¥TypeScript 4.5 supports an ECMAScript proposal for checking whether an object has a private field on it.
You can now write a class with a #private
field member and see whether another object has the same field by using the in
operator.
ts
class Person {#name: string;constructor(name: string) {this.#name = name;}equals(other: unknown) {return other &&typeof other === "object" &&#name in other && // <- this is new!this.#name === other.#name;}}
此功能的一个有趣之处在于,检查 #name in other
意味着 other
必须构造为 Person
,因为该字段不可能以其他方式存在。这实际上是该提案的关键特性之一,也是该提案被命名为 “符合人机工程学的品牌检查” 的原因。 - 因为私有字段通常充当 “brand” 的作用,以防止出现非其类实例的对象。因此,TypeScript 能够在每次检查时适当地缩小 other
的类型范围,直到最终得到 Person
类型。
¥One interesting aspect of this feature is that the check #name in other
implies that other
must have been constructed as a Person
, since there’s no other way that field could be present.
This is actually one of the key features of the proposal, and it’s why the proposal is named “ergonomic brand checks” - because private fields often act as a “brand” to guard against objects that aren’t instances of their class.
As such, TypeScript is able to appropriately narrow the type of other
on each check, until it ends up with the type Person
.
我们要衷心感谢彭博 此拉取请求的贡献者 的朋友们:Ashley Claymore、Titian Cernicova-Dragomir、Kubilay Kahveci 和 Rob Palmer!
¥We’d like to extend a big thanks to our friends at Bloomberg who contributed this pull request: Ashley Claymore, Titian Cernicova-Dragomir, Kubilay Kahveci, and Rob Palmer!
导入断言
¥Import Assertions
TypeScript 4.5 支持 ECMAScript 提案,用于导入断言。这是运行时用来确保导入具有预期格式的语法。
¥TypeScript 4.5 supports an ECMAScript proposal for import assertions. This is a syntax used by runtimes to make sure that an import has an expected format.
ts
import obj from "./something.json" assert { type: "json" };
由于这些断言是特定于宿主的,因此 TypeScript 不会检查它们的内容,因此它们只是被保留下来,以便浏览器和运行时能够处理它们(并且可能出现错误)。
¥The contents of these assertions are not checked by TypeScript since they’re host-specific, and are simply left alone so that browsers and runtimes can handle them (and possibly error).
ts
// TypeScript is fine with this.// But your browser? Probably not.import obj from "./something.json" assert {type: "fluffy bunny"};
动态 import()
调用还可以通过第二个参数使用导入断言。
¥Dynamic import()
calls can also use import assertions through a second argument.
ts
const obj = await import("./something.json", {assert: { type: "json" },});
第二个参数的预期类型由名为 ImportCallOptions
的新类型定义,目前仅接受 assert
属性。
¥The expected type of that second argument is defined by a new type called ImportCallOptions
, and currently only accepts an assert
property.
我们要感谢 Wenlu Wang 和 实现此功能!
¥We’d like to thank Wenlu Wang for implementing this feature!
JSDoc 中的常量断言和默认类型参数
¥Const Assertions and Default Type Arguments in JSDoc
TypeScript 4.5 为我们的 JSDoc 支持带来了一些额外的表达能力。
¥TypeScript 4.5 brings some extra expressivity to our JSDoc support.
const
断言就是一个例子。在 TypeScript 中,可以通过在字面量后写入 as const
来获得更精确且不可变的类型。
¥One example of this is with const
assertions. In TypeScript, you can get a more precise and immutable type by writing as const
after a literal.
ts
// type is { prop: string }let a = { prop: "hello" };// type is { readonly prop: "hello" }let b = { prop: "hello" } as const;
在 JavaScript 文件中,现在可以使用 JSDoc 类型断言来实现同样的效果。
¥In JavaScript files, you can now use JSDoc type assertions to achieve the same thing.
ts
// type is { prop: string }let a = { prop: "hello" };// type is { readonly prop: "hello" }let b = /** @type {const} */ ({ prop: "hello" });
提醒一下,JSDoc 类型断言注释以 /** @type {TheTypeWeWant} */
开头,后跟一个带括号的表达式:
¥As a reminder, JSDoc type assertions comments start with /** @type {TheTypeWeWant} */
and are followed by a parenthesized expression:
js
/** @type {TheTypeWeWant} */` (someExpression)
TypeScript 4.5 还为 JSDoc 添加了默认类型参数,这意味着 TypeScript 中的以下 type
声明:
¥TypeScript 4.5 also adds default type arguments to JSDoc, which means the following type
declaration in TypeScript:
ts
type Foo<T extends string | number = number> = { prop: T };
可以在 JavaScript 中重写为以下 @typedef
声明:
¥can be rewritten as the following @typedef
declaration in JavaScript:
js
/*** @template {string | number} [T=number]* @typedef Foo* @property prop {T}*/// or/*** @template {string | number} [T=number]* @typedef {{ prop: T }} Foo*/
更多信息,请参阅 关于 const 断言的拉取请求 以及 类型参数默认值的更改。
¥For more information, see the pull request for const assertions along with the changes for type argument defaults.
使用 realPathSync.native
缩短加载时间
¥Faster Load Time with realPathSync.native
TypeScript 现在在所有操作系统上都利用 Node.js realPathSync
函数的系统原生实现。
¥TypeScript now leverages a system-native implementation of the Node.js realPathSync
function on all operating systems.
之前此功能仅在 Linux 上使用,但在 TypeScript 4.5 中,它已被用于通常不区分大小写的操作系统,例如 Windows 和 MacOS。在某些代码库中,此更改将项目加载速度提高了 5-13%(取决于宿主操作系统)。
¥Previously this function was only used on Linux, but in TypeScript 4.5 it has been adopted to operating systems that are typically case-insensitive, like Windows and MacOS. On certain codebases, this change sped up project loading by 5-13% (depending on the host operating system).
更多信息,请参阅 原始变更在此 以及 此处是 4.5 的具体更改。
¥For more information, see the original change here, along with the 4.5-specific changes here.
JSX 属性的代码片段补全
¥Snippet Completions for JSX Attributes
TypeScript 4.5 为 JSX 属性带来了代码片段补全功能。在 JSX 标签中写出属性时,TypeScript 会为这些属性提供建议;但是使用代码片段补全功能,它们可以通过添加初始化器并将光标放在正确的位置来减少一些额外的输入。
¥TypeScript 4.5 brings snippet completions for JSX attributes. When writing out an attribute in a JSX tag, TypeScript will already provide suggestions for those attributes; but with snippet completions, they can remove a little bit of extra typing by adding an initializer and putting your cursor in the right place.
TypeScript 通常使用属性的类型来确定要插入哪种初始化器,但你可以在 Visual Studio Code 中自定义此行为。
¥TypeScript will typically use the type of an attribute to figure out what kind of initializer to insert, but you can customize this behavior in Visual Studio Code.
请记住,此功能仅适用于较新版本的 Visual Studio Code,因此你可能需要使用 Insiders 版本才能使其正常工作。详情请见 阅读原始拉取请求信息。
¥Keep in mind, this feature will only work in newer versions of Visual Studio Code, so you might have to use an Insiders build to get this working. For more information, read up on the original pull request
更好地处理未解析类型的编辑器支持
¥Better Editor Support for Unresolved Types
在某些情况下,编辑器会利用轻量级的 “partial” 语义模式。 - 编辑器等待完整项目加载时,或在类似 GitHub 的网页编辑器 的上下文中。
¥In some cases, editors will leverage a lightweight “partial” semantic mode - either while the editor is waiting for the full project to load, or in contexts like GitHub’s web-based editor.
在旧版本的 TypeScript 中,如果语言服务找不到类型,它只会打印 any
。
¥In older versions of TypeScript, if the language service couldn’t find a type, it would just print any
.
在上面的例子中,Buffer
未找到,因此 TypeScript 在快速信息中将其替换为 any
。在 TypeScript 4.5 中,TypeScript 会尽力保留你编写的内容。
¥In the above example, Buffer
wasn’t found, so TypeScript replaced it with any
in quick info.
In TypeScript 4.5, TypeScript will try its best to preserve what you wrote.
但是,如果将鼠标悬停在 Buffer
本身上,你会收到一条提示,提示 TypeScript 找不到 Buffer
。
¥However, if you hover over Buffer
itself, you’ll get a hint that TypeScript couldn’t find Buffer
.
总之,当 TypeScript 没有完整的程序可用时,这可以提供更流畅的体验。请记住,在常规情况下,当找不到类型时,你始终会收到一条错误消息。
¥Altogether, this provides a smoother experience when TypeScript doesn’t have the full program available. Keep in mind, you’ll always get an error in regular scenarios to tell you when a type isn’t found.
更多信息请见 查看此处的实现!
¥For more information, see the implementation here.
打破变更
¥Breaking Changes
lib.d.ts
变更
¥lib.d.ts
Changes
TypeScript 4.5 对其内置声明文件进行了一些更改,这可能会影响你的编译;然而,这些变化相当小,我们预计大多数代码不会受到影响。
¥TypeScript 4.5 contains changes to its built-in declaration files which may affect your compilation; however, these changes were fairly minimal, and we expect most code will be unaffected.
与 Awaited
相比的推断变化
¥Inference Changes from Awaited
由于 Awaited
现在在 lib.d.ts
中使用,并且作为 await
的结果,你可能会看到某些泛型类型的变化,这可能会导致不兼容;但是,考虑到围绕 Awaited
的许多有意设计决策以避免破坏,我们预计大多数代码不会受到影响。
¥Because Awaited
is now used in lib.d.ts
and as a result of await
, you may see certain generic types change that might cause incompatibilities;
however, given many intentional design decisions around Awaited
to avoid breakage, we expect most code will be unaffected.
在 tsconfig.json
根目录检查编译器选项
¥Compiler Options Checking at the Root of tsconfig.json
很容易忘记 tsconfig.json
中的 compilerOptions
部分。为了帮助纠正这个错误,在 TypeScript 4.5 中,如果在 tsconfig.json
中未定义 compilerOptions
,则添加与 compilerOptions
中任何可用选项匹配的顶层字段是错误的。
¥It’s an easy mistake to accidentally forget about the compilerOptions
section in a tsconfig.json
.
To help catch this mistake, in TypeScript 4.5, it is an error to add a top-level field which matches any of the available options in compilerOptions
without having also defined compilerOptions
in that tsconfig.json
.