TypeScript 7.0:不只是变快
TypeScript 7.0 用 Go 重写了编译器,带来 8-12 倍编译加速。但真正影响日常开发的,是那些静默改变的默认配置。聊聊这次升级里值得关注的变化。
7 月 8 号,TypeScript 7.0 正式发布了。这可能是 TS 自诞生以来最大的一次基础架构变更——整个编译器从 TypeScript/JavaScript 移植到了 Go。
我第一时间在一个中型项目上试了试,tsc --noEmit 从原来的 4.3 秒变成了 0.5 秒。说实话,体感差别比数字更大——以前是"按下回车后切到浏览器看一眼",现在是"按下回车就已经完了"。
但这个版本真正值得聊的,不只是性能。
为什么是 Go
TypeScript 团队选 Go 做原生端口的理由很务实。Go 编译为机器码,没有 JIT 预热,启动即全速。goroutine 和共享内存模型天然适合并行化编译任务。而且 Go 编译为单一二进制文件,跨平台分发简单——不需要用户装任何运行时。
移植策略是"尽可能忠实地移植"——保持原有代码的结构和逻辑,确保两个编译器的输出一致。在这基础上,利用 Go 的原生性能和共享内存多线程实现量级提升。
性能到底提升多少
官方的基准测试数据挺实在的,跑的是真实项目:
| 项目 | TS 6 编译时间 | TS 7 编译时间 | 加速比 |
|---|---|---|---|
| vscode | 125.7s | 10.6s | 11.9x |
| sentry | 139.8s | 15.7s | 8.9x |
| bluesky | 24.3s | 2.8s | 8.7x |
| playwright | 12.8s | 1.47s | 8.7x |
| tldraw | 11.2s | 1.46s | 7.7x |
更好的是,加速的同时内存占用反而降低了。VS Code 的编译内存峰值从 5.2GB 降到了 4.2GB,减少了 18%。这对 CI 环境和内存紧张的开发机器都是实打实的好处。
默认 4 个 checker worker,调到 8 个还能进一步压榨性能——vscode 项目在 8 个 checker 下达到 16.7 倍加速。当然,团队也提醒 CI 环境可以设 --checkers 1 减少重复计算、降低内存。
编辑器体验:从"倒杯水"到"打开即见"
性能提升在编辑器里更明显。以 VS Code 自身代码库为例,以前打开一个包含错误的文件,从打开到看到红色波浪线需要约 17.5 秒——够你去倒杯水了。TS 7 把这个时间缩短到了 1.3 秒以下。
Slack 的工程师说 TS 7 消除了他们 40% 的合并队列等待时间,CI 类型检查从 7.5 分钟降到 1.25 分钟。Canva 的编辑器首次错误提示从 58 秒降到 4.8 秒。微软 News Services 团队每月省了 400 小时的 CI 等待时间。
这些数字背后是真实的开发体验改善。不是你"感觉快了",而是那些原本被打断的注意力片段被接回去了。
默认配置的静默变更
性能提升是显性的,但真正可能给你带来麻烦的,是那些悄悄改掉的默认值。
**strict: true 默认开启。**这意味着 noImplicitAny、strictNullChecks 等全部严格检查默认打开。新项目直接受益,老项目如果之前没开 strict,升级后可能会看到一片红。
**module: "esnext" 默认。**不再默认输出 CommonJS。如果项目配置依赖了默认的 CommonJS 行为,升级后需要显式设置 module。
**rootDir: "./" 默认。**过去很多项目不设置 rootDir 也能正常工作,现在如果你的 tsconfig.json 在项目根目录而源码在 src/ 下,不显式指定 rootDir: "./src" 就会出问题。
**types: [] 默认。**这个影响最大。以前 @types/node、@types/jest 等包会自动加载,现在你必须手动声明。如果你的代码里用了 process.env 或 Buffer 但没在 types 里声明 node,升级后会直接报错。
{
"compilerOptions": {
"types": ["node", "jest"]
}
}
**stableTypeOrdering: true 且不可关闭。**类型排序变得稳定,意味着生成的 .d.ts 文件不再因编译顺序不同而变化。对库作者来说这是个好改动——diff 会更干净——但如果你的代码依赖了某种隐式的类型顺序,可能需要调整。
彻底告别的旧特性
TS 6 中标记为废弃的特性,在 7.0 中变成了硬错误:
- **
target: es5不再支持。**ES5 编译目标正式退役。 - **
module: amd / umd / systemjs / none不再支持。**推荐用esnext或preserve。 - **
moduleResolution: node / node10 / classic不再支持。**推荐用bundler或nodenext。 baseUrl不再支持。paths改用相对项目根的写法。esModuleInterop和allowSyntheticDefaultImports不能设为 false。- **导入上的
asserts关键字必须改为with,**与 ECMAScript Import Attributes 语法对齐。
方向很明确:TypeScript 在全面拥抱现代 ECMAScript 生态。如果你还在维护依赖 AMD 模块或 ES5 输出的老项目,这次升级不是 npm install 就完事的。
迁移建议
如果你的项目已经在 TS 6 上并且开启了 strict,升级到 7 的改动不会太大。主要检查几个点:
- 确认
rootDir是否需要显式设置 - 确认
types字段是否声明了所有需要的类型包 - 检查是否有依赖 ES5 目标或旧模块系统的配置
- 确认
paths使用了相对项目根的写法(不再依赖baseUrl)
如果你的项目还在 TS 5 甚至更早,建议先升到 TS 6 过渡,再上 7。TS 7 不提供程序化 API(API 将在 7.1 引入),所以像 typescript-eslint 这类依赖 TS API 的工具暂时需要用 @typescript/typescript6 兼容包。Vue、MDX、Astro、Svelte 等嵌入式语言的项目也暂时只能用 TS 6——这些框架依赖 Volar 等工具的 API 集成,需要等 7.1。
最后
TypeScript 7.0 最让人高兴的地方在于:它不是加了花哨的新语法,而是把基础设施做好了。编译器变快了,编辑器不卡了,内存占用降了。这些改进不会让你在 Twitter 上发出一条"卧槽"的推文,但它们会每天都在帮你省时间。
而且,用 Go 重写意味着 TypeScript 编译器从此可以脱离 Node.js 运行。这对未来工具链的想象空间很大——比如可能不再需要为了跑 tsc 而在 CI 里装一套 Node 环境。
200 万行 TypeScript 代码翻译成 Go,这不是一个小工程。微软的 TypeScript 团队做了一件很扎实的事。