代码 TypeScript 5.9:import defer 延迟模块求值,大项目编译快约 11%

2026-09-20 21:02:41

TypeScript 5.9:import defer 延迟模块求值,大项目编译快约 11%

2025-08-01 发布的 TypeScript 5.9 主要围绕模块求值、--module node20 稳定化、编辑器悬停体验,以及编译器内部实例化与文件检查的优化。下面按变更点过一遍。

tsc --init 生成的默认配置精简了

现在直接跑 tsc --init,产出的 tsconfig.json 去掉了大量注释内容,只留精简骨架。生成的 compilerOptions 大致是:

{
"compilerOptions": {
"module": "nodenext",
"target": "esnext",
"types": [],
"sourceMap": true,
"declaration": true,
"declarationMap": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"strict": true,
"jsx": "react-jsx",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true
}
}

如果项目里已有旧的 tsconfig.json,不用跟着改;新建项目时注意这些默认项比过去严格。

import defer:延迟模块求值

import defer 对应 ECMAScript 的 deferred module evaluation。它允许引入一个模块但不立刻执行该模块及其依赖,只有第一次真正使用时才求值:

import defer * as expensiveLibrary from "expensive-library";

规则很明确:不能用命名导入,也不能用默认导入,只能整模块命名空间导入。典型场景是按条件加载初始化代价高、或依赖特定平台的模块,用来改善启动性能。

--module node20 成为稳定选项

--module node20 现在是一个稳定选项,对齐 Node.js v20 的行为。与 --module nodenext / --moduleResolution nodenext 不同,它不太可能再引入新行为,适合想锁定语义、不想被后续 Node 版本行为拖动的项目。

迁移时要注意 target 的隐含关系:

  • 指定 --module node20 会隐含 --target es2023,除非显式配置;
  • --module nodenext 隐含的是浮动的 --target esnext

DOM API 摘要与可展开悬停

悬停提示现在会带上基于 MDN 的摘要描述,查看 DOM API 时不必再跳文档。

VS Code 中新增可展开悬停(预览):快速信息里出现 + / - 按钮,用于展开或折叠深层嵌套的类型。

悬停长度也可配置了。语言服务器支持 VS Code 的 js/ts.hover.maximumLength,新的默认值比之前大不少,长类型不再被截断得那么早。

编译性能:mapper 实例化缓存与文件存在性检查

  • 当某个具体类型实例化的工作已经开始时,编译器会在 mapper 上缓存大量中间实例化结果。这同时避免了在 Zod、tRPC 这类复杂库中出现「过度的类型实例化深度」报错。
  • 优化了文件存在性检查(fileOrDirectoryExistsUsingSource),在较大项目上大约有 11% 的提速。

值得注意的行为变更

ArrayBuffer 不再是若干 TypedArray 类型的超类型,其中也包括 Uint8Array 的子类型(例如 Node.js 的 Buffer)。升级后会看到新的报错信息,类型参数推断也有变化。

迁移提醒:遇到相关报错时,把接收 ArrayBuffer 的位置改成显式的 TypedArray 类型(如 Uint8Array),不要继续依赖 ArrayBuffer 作为父类型来接收 Buffer

链接

  • 发布公告:
  • 5.9 Release Notes:
复制全文 生成海报 TypeScript 前端 JavaScript 编译优化

推荐文章

程序员茄子在线接单