TypeScript 7.0 迁移实录:10 倍提速是真的,但不是所有人都能上车
TypeScript 7.0 GA 发布于 7 月 8 日,编译器用 Go 重写后实测 8-12 倍提速。本文记录了迁移过程中的真实体验:哪些项目能迁、哪些要等、以及为什么这次升级不是简单的 npm install。
7 月 8 日,TypeScript 7.0 正式发布了。这不是一个普通的 semver major 版本——TypeScript 编译器从 TypeScript/JavaScript 完全移植到了 Go。微软的用词是「port」,不是「rewrite」,意味着类型检查逻辑在结构上和 6.0 保持一致,只是运行环境从 Node.js 换成了原生 Go 二进制。
我自己在几个项目上跑了一轮迁移,趁热写一下实际体验。不是翻译官方博客,主要是讲哪些地方跟预期不一样、踩了什么坑、以及对不同规模的项目我的建议是什么。
速度数字:别只记一个「10x」
「10 倍提速」这个说法覆盖了微软官方给的多个数据,但不同场景下的数字差异挺大。以下是 GA 博文里官方公布的五个标准代码库的完整构建对比(默认设置,4 个 checker 线程):
| 项目 | TS 6.0 | TS 7.0 | 提速 |
|---|---|---|---|
| VS Code | 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 |
所以实际区间是 7.7x 到 11.9x,微软说的「8x 到 12x」是合理的概括。如果你把 checker 线程数从默认的 4 调到 8(--checkers 8),VS Code 这个项目还能再压到 7.51s,变成 16.7x——但这属于调优配置,不是开箱即用的数字。
另外 VS Code 团队自己在博客里给的是另一个维度的数字:tsc --noEmit -p src/tsconfig.json 从 36 秒降到 5 秒(约 7x),完整的 npm run watch(约 50 个 tsconfig 项目)从 80 秒降到 20 秒(约 4x)。这些场景和 GA 基准测试的测量口径不一样,不能直接平均。
内存方面,几个项目也同步下降了。VS Code 从 5.2GB 降到 4.2GB(-18%),Bluesky 从 1.8GB 降到 1.3GB(-26%)。更快的同时还更省内存,这个比较少见到。
我自己在项目里跑的结果:一个约 12 万行的 Next.js 项目,tsc --noEmit 从 23 秒降到了 2.7 秒,大概 8.5x。编辑器里的诊断延迟体感上从「够喝口水」变成了「基本实时」。说实话,这个差别比你想象的大——以前那种「改了代码,盯着左下角转圈,等红色波浪线出来」的体验,现在基本消失了。
编辑器体验:最直观的变化
命令行编译快 10 倍当然好,但大多数人日常感知最强的是编辑器里的类型检查反馈。微软给了一个数据:在 VS Code 代码库里打开一个文件,从打开到看到第一个错误提示,TS 6 需要 17.5 秒,TS 7 只需要不到 1.3 秒——超过 13 倍的提升。
17.5 秒够你刷一下手机了,1.3 秒就是眨眼的功夫。
Slack 的工程师在 Bluesky 上说,他们之前因为语言服务器加载太慢,几乎不在本地做类型检查,全靠 CI 跑。升级后本地几秒就能加载,合并队列时间减少了 40%,CI 类型检查从 7.5 分钟降到了 1.25 分钟。
我用了差不多一周的感觉是:以前打开项目后我会下意识先干点别的等它加载完,现在这个等待已经短到不需要特意留意了。这是那种「用了就回不去」的体验升级。
谁不能上车:API 缺位
这是这次发布最大的坑,也是最重要的前置信息。TypeScript 7.0 没有提供稳定的 programmatic API。微软说 7.1 版本预计 3-4 个月后发布,到时候会有新的 API。
这意味着什么?任何需要从代码里调用 TypeScript 编译器 API 的工具,全部不能升级。具体来说:
- Vue(vue-tsc)
- Svelte
- Astro
- MDX
- Angular 的模板类型检查
- typescript-eslint
- ts-loader(Webpack)
- 各种构建工具的 TypeScript 插件
这些生态工具目前只能继续用 TS 6.0。如果你用的是 Next.js 或纯 React 项目,直接用 tsc 做类型检查,那没问题。但如果你在 Vue/Svelte 项目里,编辑器里还得继续用 6.0 的语言服务。
微软提供了一个兼容方案:发布了一个 @typescript/typescript6 包,提供 tsc6 可执行文件并重新导出 TS 6.0 的 API。你可以同时装 TS 7.0 和这个兼容包,命令行用 tsc 跑 7.0,编辑器里的工具链继续用 6.0。
对于 Angular 项目,微软的建议是:命令行用 7.0 的 tsc 跑全项目错误检测,编辑器用 6.0 获取模板内的类型支持。两个版本并存,各司其职。
迁移实操:别直接改 package.json
很多人第一反应是 npm install -D typescript@latest,然后就完事了。实际上正确姿势是把 CLI 和 API 分开。
推荐的迁移步骤:
第一步,安装原生 CLI:
npm install -D typescript@7
这个包现在指向 TS 7.0 的 tsc,是 Go 编译的原生二进制。
第二步,让工具链继续用 TS 6.0 的 API:
npm install -D @typescript/typescript6
然后在 package.json 里用 npm alias:
{
"devDependencies": {
"typescript": "npm:@typescript/typescript6@^6.0.0",
"typescript7": "npm:typescript@^7.0.0"
}
}
这样 npx tsc 默认还是走 7.0(因为 typescript7 包里也有 tsc 命令),而依赖 typescript 包 API 的工具(比如 typescript-eslint)则走 6.0。
第三步,处理 tsconfig 的默认值变更。
TS 7.0 继承了 6.0 的默认配置变更,并且把 6.0 里标记为弃用的配置升级成了硬错误。如果你的项目在 TS 6.0 下已经干净编译,那类型层面不会有变化。但有几个地方需要注意:
strict现在默认为true。如果你之前没开,升级后会多出一堆类型错误。建议先开strict把 TS 6.0 下的问题修完再升 7.0。types现在默认为空数组[],不再自动包含所有@types包。以前装了@types/node就能直接用,现在必须显式写在tsconfig.json里。rootDir现在默认是./,不再自动推断。如果你的tsconfig.json在项目根目录、代码在src/下,需要显式指定"rootDir": "./src"。target: "es5"不再支持。moduleResolution: "node"/"node10"不再支持,改用"nodenext"或"bundler"。baseUrl不再支持,paths现在相对于项目根目录解析。esModuleInterop和allowSyntheticDefaultImports不能再设为false。
另外,JS 文件(allowJs / checkJs)的处理方式被重新梳理了。以前 TS 对 .js 文件的分析依赖一堆 JSDoc 惯例和 Closure Compiler 兼容逻辑,跟 .ts 文件的分析有不少不一致。7.0 重写了 JS 支持,让两者行为更统一。几个影响:
- 不能在类型位置直接使用值,要写
typeof someValue @enum不再特殊识别,用@typedef+keyof替代- 单独的
?不能做类型,用any代替 - Closure 风格的函数类型语法
function(string): void不再支持,改为(s: string) => void
如果你项目里有大量 JSDoc 类型标注的 .js 文件,建议先在 TS 6.0 下跑一遍,看看有没有警告。
值得迁吗?
纯 React / Next.js / Node.js 项目:值得,而且现在就可以迁。收益是实打实的——tsc --noEmit 快一个数量级,编辑器反馈基本实时,CI 时间明显缩短。迁移成本主要是 tsconfig 调整和 CLI/API 拆分,工作量大半天到一个工作日。
Vue / Svelte / Astro / MDX 项目:现在迁不了,等 7.1。不过你可以先在命令行装 7.0 跑 tsc --noEmit 做补充检查,编辑器继续用 6.0。聊胜于无,但至少能享受到快速的命令行类型检查。
大型 monorepo:看你们的构建工具链复杂度。如果依赖大量 TS API 的插件(typescript-eslint、webpack 插件等),建议先在一两个子项目上试点,CI 跑通了再铺开。微软内部团队(Loop、Office、PowerBI、Teams、Xbox)和外部的 Bloomberg、Canva、Figma、Google 等都参与了预发布测试,反馈不错,但人家有专门的 infra 团队做适配。
最后
TypeScript 7.0 是一个比较难得的升级——性能提升是数量级的,类型检查逻辑又保持不变,迁移风险相对可控。但「没有 API」这个限制在 7.1 出来之前会挡住相当一部分人。这不是 bug,是发布时间线的取舍——团队选择先把命令行和编辑器体验交付出来,API 在下一个版本补上。
对能用的人来说,速度一旦提上去了,就真的回不去了。