微软发布了 TypeScript 7.0 的首个候选版本(RC),其核心变化不是新语言特性,而是编译器本身被完整地用 Go 语言重写了。结果是:类型检查比 TypeScript 6.0 快了大约 10 倍。
这是一个令人印象深刻的数字,但它的意义远不止于速度。TypeScript 是当今全球使用最广泛的编程语言之一,也是 JavaScript 生态中最重要的基础设施之一。把整个编译器从一个自举的 TypeScript/JavaScript 代码库移植到 Go 语言,这既是一次工程上的豪赌,也是一个经过深思熟虑的技术决策。Daniel Rosenwasser 在公告中强调,类型检查逻辑「在结构上与 TypeScript 6.0 完全相同」,保证语义不变的前提下,所有性能收益完全来自原生代码执行和共享内存并行。

编译器用另一种语言重写自己的故事在软件史上并不少见,但放在 TypeScript 身上,这个决定有额外的分量。TypeScript 一直以「JavaScript 的超集」自居,编译器本身也一贯用 TypeScript 编写(自举),这既是信念的象征,也是社区贡献门槛的保障——任何 JavaScript 开发者都能读懂和修改编译器源码。选择 Go 语言打破了这一传统。团队显然在性能的迫切需求和社区的熟悉度之间做出了取舍。Go 的并发原语(goroutine 和 channel)、编译为目标平台原生二进制的能力、以及轻量级的运行时,使它成为一个合理的选择,但与 Rust 或 Zig 相比,TypeScript 团队最终选择了开发者体验更平滑的路径。
并行化是速度提升的核心引擎。TypeScript 7.0 引入了三个控制并行度的命令行标志:--checkers 设定类型检查工作线程数(默认 4 个)、--builders 设定并行项目引用构建器数量、--singleThreaded 则将一切限制为单线程。检查器的并行策略是创建一个固定大小的 worker 池,每个 worker 持有独立的程序视图,文件在 worker 之间均分分配以保证确定性。构建器的并行则允许同时构建多个项目,在 monorepo 场景中尤其有效。需要注意的是,--checkers 和 --builders 的组合是乘法效应——4 个 checker 加 4 个 builder 意味着最多 16 个类型检查器同时运行,所以调优是必要的。除类型检查外,解析和生成输出文件也实现了跨文件的并行化,在大型代码库中收益显著。
文件监听模式(--watch)也得到了一个值得单独讨论的改进。TypeScript 7.0 的文件监视器从 Parcel 的 C++ 实现的 @parcel/watcher 移植到了 Go 语言原生的实现,只保留了极少的汇编层代码。这个选择不仅消除了 C++ 工具链的依赖,还在各平台上实现了显著的资源占用改善。团队在评估了纯轮询方案后认为其「对通用场景负担过重」,最终选择了基于操作系统原生事件机制的方向。这对于在大型 monorepo 中运行 tsc --watch 的开发者来说是一个直接的利好——旧版的文件监听在数万个文件的环境中常常成为 CPU 和内存的瓶颈。
TypeScript 7.0 的破坏性变更值得认真梳理。TS 6.0 中标记为废弃的特性在 7.0 中全部变成了硬错误。具体包括:target: es5 不再支持,downlevelIteration 被移除,moduleResolution: node 和 node10 必须改用 nodenext 或 bundler,module: amd/umd/systemjs/none 被移除(使用 esnext 或 preserve),baseUrl 被移除(paths 需要相对于项目根目录配置),moduleResolution: classic 必须改用 bundler 或 nodenext,esModuleInterop 和 allowSyntheticDefaultImports 不允许设为 false,alwaysStrict 被假定为 true 且无法关闭,module 关键字不能出现在命名空间声明中,import 的 asserts 关键字必须改用 with 以对齐 ECMAScript 标准。
两个对项目配置影响最大的默认值变更是 rootDir 和 types。rootDir 现在默认为 ./——如果你的 tsconfig.json 不在源码目录中,需要显式声明。types 的旧版自动包含行为被取消,如果需要恢复旧行为需要设置 "types": ["*"],或者显式列出所需包如 ["node", "jest"]。strict、module: esnext、target 默认值(当前稳定 ECMAScript 版本)等关键选项的新默认值也从 TS 6.0 延续了下来。
模板字面量类型的推断现在遵循 Unicode 码点而非 UTF-16 代码单元。这个修改解决了一个长期存在的问题:在之前的版本中,HeadTail<"*abc"> 的结果是 ["\ud83d", "\ude00abc"],因为 JS 的字符串索引(charAt 和 [0])会分割代理对。TypeScript 7.0 改为遵循 for...of 和 [...str] 的迭代语义,将每个码点视为一个单元,结果变成了 ["*", "abc"]。对于依赖旧行为的类型级工具来说,这是一个需要关注的破坏性变更。
JavaScript 文件的类型分析也进行了大幅收紧,使其与 .ts 文件的分析行为保持一致。在值需要类型的地方必须使用 typeof someValue,@enum 不再被特别识别,独立的 ? 需要用 any 替代,@class 不再将函数变为构造函数,后置 ! 不再支持,类型名称必须放在 @typedef 标签内,闭包风格的函数语法被拒绝,this 的别名和整体 prototype 重写也不再做特殊处理。微软维护了一份动态更新的 CHANGES.md 来追踪两版本之间的所有 JS 差异。
编辑器体验方面,TypeScript 7.0 基于 LSP 协议构建了新的语言服务器,利用多线程处理并发请求。自预览版以来,已添加了自动导入、展开的悬停提示、嵌入提示、代码镜头、跳转到源码定义、JSX 链接编辑和标签补全等功能。Beta 之后又增加了语义高亮、「整理导入」和「移除未使用的导入」等功能。团队对顶级的 TS/JS GitHub 代码库进行了模糊测试,声称「失败的语言服务器命令相比 TypeScript 6.0 减少了超过 20 倍」。目前提供一个「TypeScript Native Preview」VS Code 扩展,稳定的程序化 API 要等到几个月后的 TypeScript 7.1。
从编译器的 10 倍提速到破坏性变更的梳理,TypeScript 7.0 是一次需要整个生态共同配合的升级,而不仅仅是开发者个人更新版本号。好在微软这次同步提供了清晰的迁移剧本和工具。
参与 Beta 测试的公司名单包括了被广泛使用的工具的核心开发者:Bloomberg、Canva、Figma、Google、Lattice、Linear、Miro、Notion、Slack、Vanta、Vercel 和 VoidZero 等。这个阵容覆盖了从 IDE(VS Code 的幕后团队)、设计工具到协作平台的各种重度 TypeScript 用户,构成了对编译器正确性和性能的严峻压力测试。
值得注意的是,TypeScript 7.0 并不打算在发布时就稳定其程序化 API。这意味着像 Angular、ESLint 和 ts-morph 这类依赖 TypeScript 编译 API 的工具在 TS 7.0 中将无法以编程方式调用类型检查器。这是 Go 重写带来的一个短期代价——原先 TypeScript 自举的编译器天然暴露了丰富的 JS API,而 Go 版本需要重新设计跨语言接口。微软将此目标设在了 TypeScript 7.1。
微软为此次迁移提供了一套完整的并行运行方案,体现了对生态兼容性的重视。通过 @typescript/typescript6 兼容包,开发者可以在同一个项目中同时安装 TypeScript 6.0(tsc6 命令)和 TypeScript 7.0(tsc 命令),两边互不干扰。对于生产环境的 CI 管道来说,这意味着可以逐步验证 TS 7.0 的行为,在确定一切正常后再切换。npm 的包别名机制("typescript": "npm:@typescript/typescript6@^6.0.0")使得这种并行安装无需任何自定义工具。此外,typescript@rc 的标签让早期采用者可以通过标准的 npm 安装流程接入,而 @typescript/native-preview 和 tsgo 二进制则继续服务于需要追踪最新每日构建的开发者。
稳定版本预计在 RC 发布后约一个月内正式发布,目标为 2026 年 7 月。在这段时间内,团队的重点将放在发布流程、已报告的回归问题和未来 API 能力的规划上。从更大的图景来看,TypeScript 7.0 的 Go 重写不仅仅是一次性能升级——它为 TypeScript 编译器打开了此前受限于 JavaScript 运行时的一切可能性:更高效的并行、更低的资源占用、以及与系统级工具的更深度集成。一旦 TS 7.1 稳定了程序化 API,像 Angular、ESLint 和 ts-morph 这些工具生态中的关键成员将能够以原生性能进行类型操作,这可能会改变整个 TypeScript 工具链的性能基线。
参考来源:TypeScript Blog: Announcing TypeScript 7.0 RC