TypeScript 7.0 原生移植:Go 版 tsc 实测 10.4x,JSDoc/CommonJS 破坏性变更
项目信息
- 仓库:microsoft/typescript-go
- 主仓库:microsoft/TypeScript
- 公告:A 10x Faster TypeScript
- npm 预览包:@typescript/native-preview
- VS Code 预览扩展:TypeScriptTeam.native-preview
为什么会有 Go 版:Corsa 与 Strada
微软把 TypeScript 编译器与语言服务用 Go 重写,代号 Corsa,原 JS 实现代号 Strada。目标:编辑器启动大幅加快、多数构建时间降低约 10 倍、内存占用明显下降。
大型代码库下,tsc 加载/检查慢,开发者被迫在“编辑器能快速启动”与“看到完整的源码视图”之间二选一;AI 工具也需要低延迟的大窗口语义信息。
版本路线分阶段:JS 版继续演进到 6.x。TypeScript 6.0 会引入一些 deprecations 和 breaking changes,与原生版对齐;原生版达到足够 parity 后作为 TypeScript 7.0 发布。部分项目可在 7.0 发布时直接切换;依赖某些 API、遗留配置的项目仍需继续用 6.x。官方会长期维护 JS 实现的 6.x 线。
10x 数字构成:tsc 与编辑器加载
实测 tsc 在若干 GitHub 代码库上的耗时(Current = 旧 JS 实现,Native = Go 实现):
| 代码库 | 行数 | Current | Native | 加速 |
|---|---|---|---|---|
| VS Code | 1,505,000 | 77.8s | 7.5s | 10.4x |
| Playwright | 356,000 | 11.1s | 1.1s | 10.1x |
| TypeORM | 270,000 | 17.5s | 1.3s | 13.5x |
| date-fns | 104,000 | 6.5s | 0.7s | 9.5x |
| tRPC (server + client) | 18,000 | 5.5s | 0.6s | 9.1x |
| rxjs (observable) | 2,100 | 1.1s | 0.1s | 11.0x |
编辑器场景:用 VS Code 代码库测,整个项目在编辑器里加载从约 9.6s 降到约 1.2s,约 8x。整体内存占用大致是旧实现的一半,且当时还没专门做内存优化。语言服务操作(补全、quick info、跳转定义、查找引用)也会显著提速。同时迁移到 LSP。
怎么试用:tsgo 与 VS Code 设置
typescript-go 是 TypeScript 7.0 发布期间原生移植的 staging 仓库。移植过程已完成,开发与讨论回到 microsoft/TypeScript;该仓库将于 2026 年 9 月永久归档。长期计划:该仓库内容会合入 microsoft/TypeScript。
预览安装 npm 包 @typescript/native-preview:
npm install @typescript/native-preview
npx tsgo # 用法同 tsc
TypeScript 7.0 RC 及之后,命令名就是 tsc。
预览版 VS Code 扩展在 VS Code marketplace(扩展 ID TypeScriptTeam.native-preview),需在设置里开启:
{
"js/ts.experimental.useTsgo": true
}
功能完成度:多数 done,LSP 进行中,API 未就绪
| 功能 | 状态 | 说明 |
|---|---|---|
| Program creation | done | 与 TS 6.0 同样的文件与模块解析;尚未支持所有解析模式 |
| Parsing/scanning | done | 与 TS 6.0 完全相同的语法错误 |
| Commandline 与 tsconfig.json 解析 | done | tsconfig 报错信息可能不如以前友好 |
| Type resolution | done | 与 TS 6.0 相同类型 |
| Type checking | done | 同样的错误、位置与消息;错误里的类型打印可能有差异 |
| JavaScript 专属推断与 JSDoc | done | 完整,但有意缺少一些特性;d.ts 生成有意与 TS 声明更接近 |
| JSX | done | |
| Declaration emit | done | |
| Emit (JS output) | done | |
| Watch mode | done | |
| Build mode / project references | done | |
| Incremental build | done | |
| Language service (LSP) | in progress | 几乎所有功能已实现 |
| API | not ready |
JSDoc 与 CommonJS 老项目要改哪些写法
CHANGES.md 列出 Strada(TypeScript/JS 实现)与 Corsa(Go 实现)之间有意的变更。
JavaScript 支持定位变化:Corsa 里 JS 支持的目标是“在 .js 文件里以不同语法暴露 TypeScript 特性”,严格对齐 TS 行为;Strada 有很多 TS 里根本不存在的 JS 特性,重叠特性也有不少差异。例如 Corsa 在 TS 和 JS 里用同一套调用检查规则;Strada 允许跳过类型为 any 的参数。对可选参数,Corsa 用同一规则,顺带修掉 Strada 在 JS 中 "strict": true 下的细微 bug。官方只主要支持现代 JS(ES modules、class、解构等),因此裁掉了大量未使用或少用的特性。最大一块被移除的是 Closure header 文件支持及大部分 Closure 专属特性。
JSDoc 标签与类型
- UnknownType
?→ 用any - NamepathType
Module:file~id→ 用import("file").id @class→ 用普通class声明@enum→ 用@typedef {number} E+@type {Record}@author:保持不变,但@treehouse在 Corsa 里会被解析成新标签- 以标识符命名的 typedef(
/** @typedef {T} */ typeName;)→/** @typedef {T} typeName */(Closure 特性) - Closure 函数类型语法
function(string): void→(s: string) => void - 自动 typeof 插入:
@type {o}→@type {typeof o} - JSDoc 里的值不再被当作类型解析:
@typedef {FORWARD | BACKWARD}必须写成@typedef {typeof FORWARD | typeof BACKWARD}
Expando 声明
构造函数模式不再支持:
function C() { this.property = 1; }
C.prototype.method = function() {}
改为 class:
class C { constructor() { this.property = 1; } method() {} }
- 嵌套未声明的 expando:
N.X.Y = {}要求先把中间层N.X = {}赋出来 - 构造函数里带类型注解的
this.属性不再创建属性,需用类体内的属性声明或 initializer
CommonJS
- 不再允许同一模块混用
module.exports = ...与module.exports.xxx = ...,二者只能选一种 this作为 module.exports 别名(顶层this.p = 1)→exports.p = 1- 单属性访问 require:
var readFile = require('fs').readFile;→var { readFile } = require('fs'); - 空
module.exports = {};赋值不再被忽略
Checker 层面
--skipLibCheck下的错误上报:TS 6 里冲突声明有时只报其中一个;TS 7 会一致地在所有冲突位置报错。一些以前被 skipLibCheck 完全压住的错误,现在会在非 .d.ts 文件里看到声明冲突错误。- 模板字面量类型推断遇到空占位时消费一个完整 Unicode 码点,而不是一个 UTF-16 code unit。旧实现会把 emoji 等补充平面字符拆成代理对:
type Head = S extends `${infer H}${string}` ? H : never;
type Rest = S extends `${string}${infer R}` ? R : never;
type H = Head; // Strada: "\uD83D";Corsa: "😀"
type R = Rest; // Strada: "\uDE00abc";Corsa: "abc"
"strict": false时,Corsa 不再允许省略类型为 undefined/unknown/any 的参数:
/** @param {unknown} x */
function f(x) { return x; }
f(); // 以前允许,现在报错
但 void 参数在任意 strict 模式下仍可省略。
- JS 函数体内使用
arguments不再隐含一个...args: any[]参数,需显式写 rest 参数 - JSDoc
@param最多只作用于一个函数 - Scanner:节点位置使用从文件开头算的 UTF8 offset,而非 UTF16 offset;含非 ASCII 字符的文件里节点位置会变大。
@typedef/@callback在类体内会被提升到类外,可能与外层同名声明冲突- CommonJS 里多次条件赋值 exports 属性现在按 union 处理
迁移与边界
TypeScript 7.0 原生版仍保留功能状态表里的缺口:Language service (LSP) 为 in progress,API 为 not ready。依赖某些 API、遗留配置的项目仍需继续用 6.x;官方会长期维护 JS 实现的 6.x 线。typescript-go 仓库在 2026 年 9 月永久归档后,开发和讨论回到 microsoft/TypeScript。