TypeScript 版本现状

2026-09-09 00:00    #typescript  

写 TypeScript 之前需要知道的第一件事:当前的 latest 是 7.0,它是一次编译器重写。很多教程上的做法已经失效。

版本格局

1$ npm view typescript dist-tags
2{
3  "latest": "7.0.2",
4  "beta": "6.0.0-beta",
5  "rc": "7.0.1-rc",
6  "next": "7.1.0-dev.20260920.1"
7}
版本实现定位
5.xJavaScript长期稳定,生态最广
6.0JavaScript最后一版 JS 实现,引入新默认值
7.0Go 原生重写当前 latest,性能大幅提升
7.1Go计划补上稳定 API

官方说法是 7.0 与 6.0 行为一致——同样的类型检查、同样的错误、同样的 JS 输出,主要收益是速度(宣称约 10 倍,来自多核并行)。语言层面没有新特性。

关键变化:没有稳定的 programmatic API

这是 7.0 最需要知道的一点。实测验证:

1$ node -e "console.log(Object.keys(require('typescript')))"
2[ 'version', 'versionMajorMinor' ]

主入口只导出两个键——版本号。没有 ts.sys,没有 ts.createProgram。

对比 TS 5.x/6.x,那时 require('typescript') 会导出完整的编译器 API(几百个符号)。

这对工具链的影响

所有依赖编译器 API 的工具都会失效:

工具状态原因
ts-node@10✗ 失效读取 ts.sys,现在是 undefined
ts-jest@29✗ 不兼容peer 依赖锁在 typescript <7
自定义 AST transformer✗ 失败编译中途报错,信息可能误导
typescript-eslint需适配需要 compiler API

Microsoft 发布了 @typescript/typescript6(当前 6.0.2)兼容包,让需要旧 API 的工具能与 7.0 并存。

新的 API 在哪里

7.0 提供了 unstable/ 前缀的实验性 API:

1$ node -e "console.log(Object.keys(require('typescript/unstable/sync')).length)"
244

可用但不稳定(unstable 前缀就是警告),且只覆盖部分能力。稳定的 API 计划在 7.1。

ts-node 失效的实测复现

1$ npx ts-node@10 run.ts
2TypeError: Cannot read properties of undefined (reading 'fileExists')
3    at readConfig (.../ts-node/dist/configuration.js:91:33)

ts.sys 是 undefined,所以读 ts.sys.fileExists 直接崩。这不是配置问题,无法绕过。

现在该怎么跑 TypeScript

方式类型检查覆盖语法依赖
tsc --noEmit + node x.ts✓(分开)仅可擦除无
tsx✗全部1 个
ts-node✓全部— ✗ 已失效
tsc 编译后 node✓全部无

详见 运行 TypeScript。

另一处变化:lib 文件移到平台包

TS 7 把 lib 文件从主包移到了平台特定的包里:

 1# 主包里已经没有 lib.es5.d.ts
 2$ ls node_modules/typescript/lib/
 3getExePath.d.ts  getExePath.js  tsc.js  version.cjs  version.d.cts
 4
 5# lib 文件在平台包里(macOS ARM 示例)
 6$ ls node_modules/@typescript/typescript-darwin-arm64/lib/ | head
 7lib.dom.d.ts
 8lib.es5.d.ts
 9lib.esnext.d.ts
10...

实际影响:lib: ["esnext"] 不再自动包含 console,会报:

1error TS2584: Cannot find name 'console'. Do you need to change your target
2library? Try changing the 'lib' compiler option to include 'dom'.

解决办法是显式声明 types:

1{ "compilerOptions": { "types": ["node"] } }

这是迁移中一个容易困惑的报错——错误消息建议你改 lib,但正确做法是加 types。

tsc --init 的默认值变严格了

TS 7 生成的配置比 5.x 时代严格得多:

 1{
 2  "compilerOptions": {
 3    "module": "nodenext",
 4    "target": "esnext",
 5    "noUncheckedIndexedAccess": true,
 6    "exactOptionalPropertyTypes": true,
 7    "strict": true,
 8    "verbatimModuleSyntax": true,
 9    "isolatedModules": true,
10    "noUncheckedSideEffectImports": true,
11    "moduleDetection": "force",
12    "skipLibCheck": true
13  }
14}

noUncheckedIndexedAccess、exactOptionalPropertyTypes、verbatimModuleSyntax 在 5.x 时代需要手动开。

别套用旧教程的配置模板

老模板会显式关掉一些现在默认开启的检查,反而降低保护。建议用 tsc --init 生成后再按需调整。

关于"faithful port"的说明

官方把 7.0 描述为"faithful port"(忠实移植)——同一份代码在 6.0 和 7.0 上应该编译出相同结果。但这有几个前提:

6.0 里被标记为 deprecated 的东西,7.0 里已经移除。所以升级检查清单是:

1# 1. 在 6.0 上编译,看有没有 deprecation 警告
2npx typescript@6 tsc --noEmit
3
4# 2. 有警告的先修掉
5
6# 3. 再升到 7.0

实测中遇到的其他差异

以下都是在写这批笔记时实际遇到的:

现象说明
tsc file.ts 报 TS5112有 tsconfig 时传文件需要 --ignoreConfig
显式 rootDir 变必需否则报 TS5011,要求明确 rootDir
console 找不到lib 移到平台包,需 types: ["node"]
递归类型上限约 1000 层比旧版本报告的 ~50 层高得多
数字枚举拒绝任意数字字面量const s: Status = 999 报错
第三方博客的可信度

关于 7.0 的中文/英文博客里,“破坏性变更"清单差异很大。有些说 ts-jest/ts-node/Vue/Svelte 全坏,有些说 strict 变成默认。可靠的做法是自己跑一遍——本仓库的所有结论都来自实际执行。

现在该选哪个版本

场景建议
新项目TS 7(快,语言行为与 6 一致)
老项目 + 用 ts-node先迁执行方式(改 tsx),再升 7
老项目 + 用 ts-jest等 ts-jest 适配,或改 swc/jest、vitest
依赖 typescript-eslint确认适配情况再升
需要 compiler API 写工具留在 6.x,或用 @typescript/typescript6
迁移的最小改动路径
  1. 类型检查:tsc --noEmit(7.0 不受影响)
  2. 开发执行:ts-node → tsx 或 Node 原生
  3. 测试:ts-jest → swc/jest 或 vitest
  4. 构建:不受影响(esbuild/swc/rollup 都不用 compiler API)

真正需要改的只有第 2、3 步。

相关