TypeScript 7.0 正式发布后,最吸引人的数字是:
原生编译器,全量构建通常提升 8---12 倍。
官方在 VS Code、Sentry、Playwright、Bluesky 和 tldraw 等项目上的基准结果约为 7.7---11.9 倍;同时,测试项目的构建内存使用也出现不同程度下降。TypeScript 7 使用 Go 重写编译器和语言服务,并利用原生代码、共享内存和多线程提高性能。
不过,真实项目迁移时,最容易翻车的并不是速度。
而是团队看到:
bash
npm install -D typescript
然后直接提交锁文件,让整个项目一夜之间切换到 TypeScript 7。
如果项目使用了旧版 tsconfig、TypeScript Compiler API、Vue、Svelte、Astro、MDX、Angular 模板检查或 ESLint 类型分析,这种升级方式很容易让编辑器、CI 和构建工具出现不同结果。
更稳的方式是:
bash
先让 TypeScript 6 与 7 并行
再对比结果
最后切换默认编译器

一、TypeScript 7 到底快在哪里?
TypeScript 7 不只是把原来的 JavaScript 编译器重新编译了一遍。
它的编译器和语言服务改为 Go 原生实现,并增加了多线程能力。解析、类型检查、代码输出和 Project References 构建,都可以在不同程度上并行执行。
官方给出的部分全量构建结果如下:
| 项目 | TypeScript 6 | TypeScript 7 | 加速 |
|---|---|---|---|
| VS Code | 125.7 秒 | 10.6 秒 | 11.9 倍 |
| Sentry | 139.8 秒 | 15.7 秒 | 8.9 倍 |
| Bluesky | 24.3 秒 | 2.8 秒 | 8.7 倍 |
| Playwright | 12.8 秒 | 1.47 秒 | 8.7 倍 |
| tldraw | 11.2 秒 | 1.46 秒 | 7.7 倍 |
但这些数据不能直接套到自己的项目。
项目规模、CPU 核心数、内存、Project References、声明文件生成和磁盘性能都会影响结果。
所以升级后的第一件事不是宣传"快了十倍",而是建立自己的基准。
二、先建立 TypeScript 6 的性能基线
升级前记录四项数据:
bash
全量类型检查时间
增量类型检查时间
峰值内存
CI 中的实际耗时
可以先使用系统自带的 time:
bash
/usr/bin/time -v \
npx tsc \
-p tsconfig.json \
--noEmit
macOS 可以使用:
bash
time npx tsc -p tsconfig.json --noEmit
Windows PowerShell:
bash
Measure-Command {
npx tsc -p tsconfig.json --noEmit
}
建议至少运行三次。
第一次通常包含磁盘缓存、依赖读取和初始化成本,不能只取第一次结果。
一个简单的 Node.js 测试脚本:
bash
// scripts/benchmark-tsc.mjs
import { spawnSync } from 'node:child_process';
import process from 'node:process';
const command = process.argv[2];
const args = process.argv.slice(3);
const rounds = 5;
const results = [];
if (!command) {
console.error(
'用法:node scripts/benchmark-tsc.mjs <command> [args...]',
);
process.exit(1);
}
for (let round = 1; round <= rounds; round += 1) {
const start = process.hrtime.bigint();
const result = spawnSync(command, args, {
stdio: 'inherit',
shell: false,
});
const end = process.hrtime.bigint();
const durationMs = Number(end - start) / 1_000_000;
if (result.status !== 0) {
console.error(`第 ${round} 次执行失败`);
process.exit(result.status ?? 1);
}
results.push(durationMs);
console.log(
`第 ${round} 次:${durationMs.toFixed(2)} ms`,
);
}
const sorted = [...results].sort((a, b) => a - b);
const average =
results.reduce((sum, value) => sum + value, 0) /
results.length;
console.log('\n测试结果:');
console.log(`最快:${sorted[0].toFixed(2)} ms`);
console.log(
`中位数:${sorted[Math.floor(sorted.length / 2)].toFixed(2)} ms`,
);
console.log(`平均:${average.toFixed(2)} ms`);
运行:
bash
node scripts/benchmark-tsc.mjs \
npx \
tsc -p tsconfig.json --noEmit
注意,这个脚本测的是进程总耗时,不是严格的编译器内部性能。
但它更接近开发者和 CI 实际等待的时间。
三、不要直接覆盖,先让 TypeScript 6 和 7 共存
TypeScript 7.0 暂时没有提供稳定的编程 API。依赖 typescript 包内部 API 的工具,可能仍然需要 TypeScript 6。
官方为此提供了 @typescript/typescript6 兼容包,可以让 TypeScript 6 与 TypeScript 7 同时存在。
可以将 package.json 调整为:
bash
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7",
"typescript": "npm:@typescript/typescript6@^6"
}
}
这里:
bash
typescript
仍然指向 TypeScript 6,供依赖 Compiler API 的工具使用。
而:
bash
@typescript/native
指向 TypeScript 7,并提供新的 tsc 可执行文件。
可以增加脚本:
bash
{
"scripts": {
"typecheck:ts6": "tsc6 -p tsconfig.json --noEmit --stableTypeOrdering",
"typecheck:ts7": "tsc -p tsconfig.json --noEmit"
}
}
分别运行:
bash
npm run typecheck:ts6
npm run typecheck:ts7
不要只对比退出码。
还应该对比:
bash
错误数量
错误文件
声明文件
输出目录
构建时间
峰值内存
编辑器诊断结果
四、迁移前最好先通过 TypeScript 6
TypeScript 7 的类型检查和命令行行为,主要以 TypeScript 6 为兼容基线。
官方建议:项目先在 TypeScript 6 中启用 stableTypeOrdering,并且不要依赖 ignoreDeprecations 隐藏旧配置问题。能够在这种状态下干净通过的项目,迁移 TypeScript 7 通常会更顺利。
先运行:
bash
npx tsc6 \
-p tsconfig.json \
--noEmit \
--stableTypeOrdering
如果这里已经出现新错误,不要等切换 TypeScript 7 后再一起处理。
先在 TypeScript 6 下修复,能把"类型推断变化"和"原生编译器迁移问题"分开。
五、第一个常见坑:types 默认变成空数组

TypeScript 7 中,types 默认值变为:
bash
[]
这意味着编译器不会再自动把所有可见的 @types 包加入全局环境。依赖 Node.js、Jest、Mocha 或其他全局类型的项目,需要显式声明。
升级后可能出现:
bash
Cannot find name 'process'
Cannot find name 'describe'
Cannot find name 'expect'
Cannot find name 'Buffer'
修复方式:
bash
{
"compilerOptions": {
"types": [
"node",
"jest"
]
}
}
对于前后端混合 Monorepo,不建议在根配置里一次性加入全部类型。
可以拆成:
bash
tsconfig.base.json
tsconfig.node.json
tsconfig.web.json
tsconfig.test.json
例如测试配置:
bash
{
"extends": "./tsconfig.json",
"compilerOptions": {
"types": [
"node",
"vitest/globals"
]
},
"include": [
"src/**/*.ts",
"tests/**/*.ts"
]
}
这样可以避免测试框架的全局类型污染生产代码。
六、第二个常见坑:必须显式配置 rootDir
TypeScript 7 中,rootDir 默认指向 tsconfig.json 所在目录。
如果配置文件位于项目根目录,而代码全部放在 src,升级后输出目录结构可能变成:
bash
dist/src/index.js
而旧项目预期的是:
bash
dist/index.js
官方将 rootDir 和 types 列为最容易让迁移项目感到意外的变化。
建议明确配置:
bash
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": [
"src/**/*.ts"
]
}
Monorepo 中每个子项目都应有自己的 rootDir:
bash
packages/
├── api/
│ ├── src/
│ └── tsconfig.json
├── shared/
│ ├── src/
│ └── tsconfig.json
└── web/
├── src/
└── tsconfig.json
不要只依赖根配置自动推断。
七、第三个常见坑:默认配置更现代,也更严格
TypeScript 7 采用 TypeScript 6 的新默认值,包括:
bash
strict = true
module = esnext
noUncheckedSideEffectImports = true
libReplacement = false
stableTypeOrdering = true
target 也会默认使用当前较新的稳定 ECMAScript 版本。
这意味着一个配置非常少的旧项目:
bash
{
"compilerOptions": {}
}
升级后行为可能出现明显变化。
对于存量项目,建议不要依赖默认值,把关键配置写明:
bash
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"noUncheckedSideEffectImports": true,
"rootDir": "./src",
"outDir": "./dist",
"types": [
"node"
]
}
}
显式配置不仅是为了兼容。
也能避免未来版本再次调整默认值时,项目行为悄悄改变。
八、第四个常见坑:一批旧选项已经彻底不能用了
TypeScript 7 对 TypeScript 6 中已经弃用的部分配置直接报错。
比较常见的包括:
bash
target: es5
moduleResolution: node
moduleResolution: node10
moduleResolution: classic
module: amd
module: umd
module: systemjs
module: none
baseUrl
downlevelIteration
同时:
bash
esModuleInterop
allowSyntheticDefaultImports
alwaysStrict
也不能再通过设置为 false 恢复旧行为。
旧 Node.js 项目:
bash
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
]
}
}
}
可以根据运行环境改成:
bash
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"paths": {
"@/*": [
"./src/*"
]
}
}
}
使用 Vite、Webpack、Rspack 等打包器的前端项目,可以考虑:
bash
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler",
"paths": {
"@/*": [
"./src/*"
]
}
}
}
不要机械地把所有项目都改成 NodeNext。
选择依据应该是:
bash
代码最终由 Node.js 直接运行
还是交给 Bundler 处理
九、第五个常见坑:导入断言语法已经变化
旧代码可能使用:
bash
import config from './config.json'
assert { type: 'json' };
现在应该改成导入属性:
bash
import config from './config.json'
with { type: 'json' };
TypeScript 7 不再接受旧的 asserts 导入写法。
可以先全局搜索:
bash
rg "assert\s*\{\s*type:" \
src packages
再逐个确认运行时和打包器是否支持新的语法。
不要只让 TypeScript 编译通过,还要检查:
bash
Node.js 版本
Bundler 版本
测试运行器
代码转换插件
是否能够正确执行。
十、并行参数不是越大越好

TypeScript 7 默认会创建 4 个类型检查 Worker。
可以通过:
bash
tsc --checkers 8
增加类型检查并行度。
对于 Project References,可以通过:
bash
tsc --build \
--checkers 4 \
--builders 2
控制并行构建项目的数量。官方也提供 --singleThreaded,用于调试、低资源环境或与外部并行系统配合。
但要注意:
bash
checkers × builders
可能形成乘法级并发。
例如:
bash
tsc --build \
--checkers 4 \
--builders 4
理论上可能同时出现多达 16 个类型检查 Worker。
在开发者 16 核、32GB 内存的电脑上可能很快。
放到只有 2 核、7GB 内存的 CI Runner 中,反而可能出现:
bash
频繁 GC
内存不足
CPU 抢占
构建时间波动
进程被系统终止
建议准备三档参数。
本地高性能电脑:
bash
tsc --build \
--checkers 8 \
--builders 2
普通 CI:
bash
tsc --build \
--checkers 2 \
--builders 1
问题排查:
bash
tsc --build \
--singleThreaded
最终数值必须通过自己的项目测出来。
十一、用脚本自动寻找合适并发数
可以写一个简单测试脚本:
bash
// scripts/benchmark-checkers.mjs
import { spawnSync } from 'node:child_process';
const candidates = [1, 2, 4, 6, 8];
const results = [];
for (const checkers of candidates) {
const start = process.hrtime.bigint();
const result = spawnSync(
'npx',
[
'tsc',
'-p',
'tsconfig.json',
'--noEmit',
'--checkers',
String(checkers),
],
{
stdio: 'ignore',
shell: false,
},
);
const end = process.hrtime.bigint();
const durationMs =
Number(end - start) / 1_000_000;
if (result.status !== 0) {
console.error(
`checkers=${checkers} 执行失败`,
);
process.exit(result.status ?? 1);
}
results.push({
checkers,
durationMs,
});
console.log(
`checkers=${checkers}:` +
`${durationMs.toFixed(2)} ms`,
);
}
results.sort(
(left, right) =>
left.durationMs - right.durationMs,
);
console.log(
`\n当前机器最快配置:` +
`--checkers ${results[0].checkers}`,
);
运行:
bash
node scripts/benchmark-checkers.mjs
该结果只能代表当前机器。
开发者电脑和 CI 应分别测试,不要共用一套并发值。
十二、第六个常见坑:Vue、Svelte、Astro、MDX 暂时别强切
TypeScript 7.0 目前没有稳定的编程 API。
因此,需要把 TypeScript 嵌入自身编译器或语言服务的工具,暂时不能完整切换。
官方明确指出:
bash
Vue
Svelte
Astro
MDX
相关工作流目前应继续使用 TypeScript 6。
Angular 项目可以使用 TypeScript 7 的 CLI 做项目级错误检查,但模板相关编辑器体验仍可能需要 TypeScript 6。
所以这些项目不要简单运行:
bash
npm install -D typescript@latest
更稳妥的做法是双轨运行:
bash
TypeScript 6:供框架插件和编程 API 使用
TypeScript 7:用于独立 CLI 类型检查和性能验证
等框架工具链明确宣布支持后,再切换默认版本。
十三、第七个常见坑:typescript-eslint 等工具可能仍依赖 6.x API
TypeScript 7.0 暂时不提供 Compiler API。
而很多工具会直接:
bash
import ts from 'typescript';
调用编译器内部能力。
例如:
bash
类型感知 ESLint
自定义 AST 工具
代码生成器
文档生成器
自定义 Transformer
内部类型分析脚本
这些工具不一定能立刻使用 TypeScript 7。
这也是为什么官方提供 TypeScript 6 兼容包,并推荐使用 npm Alias 让旧 API 和新 CLI 并存。
升级前可以搜索:
bash
rg "from ['\"]typescript['\"]" \
scripts tools packages
或者:
bash
rg "require\(['\"]typescript['\"]\)" \
scripts tools packages
如果项目代码直接调用了:
bash
ts.createProgram()
ts.createSourceFile()
ts.transform()
ts.TypeChecker
就不能只测试 tsc 是否成功。
还要单独测试这些内部工具。
十四、第八个常见坑:JavaScript 与 JSDoc 项目变化更大
TypeScript 7 重构了 JavaScript 文件和 JSDoc 的分析方式,使其更接近 .ts 文件。
部分旧式 JSDoc 和 Closure 风格写法不再支持,例如:
bash
把值直接当类型使用
旧式 @enum 行为
单独使用 ? 表示类型
通过 @class 把普通函数变成构造器
Closure 风格 function(string): void
这些变化主要影响:
bash
allowJs
checkJs
大型 JavaScript 项目
依赖 JSDoc 类型的旧代码库
官方维护了专门的差异记录。纯 TypeScript 项目通常影响较小,但大量使用 JSDoc 的仓库需要单独建立测试清单。
例如旧写法:
bash
/** @type {SomeRuntimeValue} */
let value;
如果 SomeRuntimeValue 是运行时变量,需要改成:
bash
/** @type {typeof SomeRuntimeValue} */
let value;
不要因为项目文件扩展名是 .js,就认为 TypeScript 7 与自己无关。
十五、推荐的完整迁移顺序
不要在一个 PR 中同时升级编译器、修改构建系统、调整模块格式和修复全部类型错误。
更稳的迁移顺序是:
第一步:固定 TypeScript 6 基线
bash
npm install -D typescript@^6
npx tsc --noEmit --stableTypeOrdering
修复全部弃用配置和新增类型错误。
第二步:显式补齐关键配置
bash
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"rootDir": "./src",
"types": [
"node"
]
}
}
第三步:安装双版本
bash
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7",
"typescript": "npm:@typescript/typescript6@^6"
}
}
第四步:在 CI 并行检查
bash
- name: TypeScript 6 compatibility
run: npm run typecheck:ts6
- name: TypeScript 7 validation
run: npm run typecheck:ts7
第五步:对比声明文件
如果发布 npm 包,分别生成声明:
bash
rm -rf artifacts/ts6 artifacts/ts7
npx tsc6 \
-p tsconfig.build.json \
--declaration \
--emitDeclarationOnly \
--outDir artifacts/ts6
npx tsc \
-p tsconfig.build.json \
--declaration \
--emitDeclarationOnly \
--outDir artifacts/ts7
diff -ru \
artifacts/ts6 \
artifacts/ts7
注意,类型排序变化可能产生无害 Diff,需要人工区分:
bash
纯顺序变化
真实类型变化
导出缺失
泛型推断改变
第六步:单独调优并行参数
分别在开发机和 CI 中测试:
bash
--checkers 1
--checkers 2
--checkers 4
--checkers 8
Monorepo 再测试不同的 --builders。
第七步:观察一到两周
重点记录:
bash
CI 平均耗时
CI P95 耗时
内存峰值
编辑器崩溃
类型错误差异
声明文件差异
框架插件异常
第八步:再切换默认版本
确认稳定后,再将 TypeScript 7 设为默认 typescript。
十六、哪些项目最值得优先升级?
优先级较高:
bash
大型 TypeScript Monorepo
Project References 项目
CI 类型检查超过一分钟
编辑器打开项目非常慢
经常使用查找引用和重命名
拥有多核开发机和 CI Runner
建议暂缓:
bash
严重依赖 Compiler API
拥有大量自定义 Transformer
Vue、Svelte、Astro、MDX 工具链未确认兼容
Angular 项目高度依赖模板语言服务
大量使用旧式 JSDoc
仍需输出 ES5
仍使用 AMD、UMD 或 SystemJS
TypeScript 7 不是所有项目都必须在发布当天升级。
对小项目而言,类型检查从 2 秒降低到 0.5 秒,实际价值可能有限。
对一个 CI 类型检查需要 8 分钟、每天运行数百次的 Monorepo,收益则非常明显。
十七、别只看编译速度,还要计算团队节省的时间
假设一个团队有 20 名开发者:
bash
每人每天类型检查 15 次
原耗时 30 秒
升级后耗时 5 秒
每天节省:
bash
20 × 15 × 25 秒
= 7500 秒
≈ 125 分钟
一个月按 22 个工作日计算:
bash
125 × 22
= 2750 分钟
≈ 45.8 小时
还没有计算:
bash
编辑器首次加载
查找引用
自动补全
重命名
CI 排队
PR 合并等待
这也是 TypeScript 7 对大型团队更有价值的原因。
但前提是升级没有引入新的工具链故障。
所以迁移目标应该是:
在兼容性可控的前提下,缩短整个开发反馈循环。
而不是只追求一张漂亮的编译器跑分截图。
十八、AI 编程时代,类型检查速度反而更重要
现在使用 AI 编程工具时,一次任务可能同时修改十几个文件。
代码生成速度变快后,新的瓶颈往往变成:
bash
类型检查
Lint
测试
构建
人工 Review
模型一分钟写完代码,但项目类型检查需要五分钟,开发反馈循环仍然很慢。
TypeScript 7 的价值并不是让 AI 更会写代码。
而是让每次生成后的验证更快:
bash
AI 修改代码
↓
立即运行类型检查
↓
快速发现跨文件错误
↓
继续修正
↓
进入测试和 Review
长期使用 ChatGPT Plus、Claude Pro、Cursor、Kiro 等工具时,可以通过 gpt68.com 了解相关第三方 AI 会员充值服务;不过,对开发团队而言,工具订阅只是准备,编译、测试和 Review 的反馈速度才真正决定 AI 编程效率。
总结
TypeScript 7.0 最明显的变化,是原生编译器和多线程带来的大幅提速。
但真正决定项目能不能顺利升级的,是下面这些问题:
bash
types 是否显式配置
rootDir 是否固定
旧 moduleResolution 是否清理
baseUrl 是否移除
运行环境是否支持新模块方案
框架插件是否兼容
Compiler API 工具如何继续运行
checkers 和 builders 是否适合当前机器
JSDoc 项目是否存在行为变化
最稳的迁移方式不是直接覆盖。
而是:
bash
TypeScript 6 建立兼容基线
TypeScript 6 与 7 双版本运行
对比错误和声明文件
单独测试插件与内部工具
根据机器调优并发
观察 CI 和编辑器稳定性
最后再切换默认版本
TypeScript 7 确实可能让大型项目的类型检查从"需要等待"变成"接近即时反馈"。
但只有把兼容性问题提前解决,这部分性能提升才会真正转化为研发效率。