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: