升到 TypeScript 7 的项目,package.json 里会同时挂着两份 TypeScript:一份用别名指向 7,一份指向 6.0 的兼容包。第一次看到的同事,多半以为是谁合并冲突没解干净。这是官方给的过渡方案:7.0 本身没带编程接口,要调编译器 API 的工具暂时只能接着用 6.0。
7.0 少了什么
TypeScript 7.0 在 7 月 8 日发布,是原生移植版,官方说多数项目完整构建能快 8 到 12 倍。官方发布文章里写得很明白:7.0 不带 API,一套和以前不一样的新 API 预计跟着 7.1 出来。在那之前,像 typescript-eslint 这种要用代码调编译器的工具,得和 6.0 并排跑。
为此官方发了一个兼容包 @typescript/typescript6。包里带一个叫 tsc6 的可执行文件,不会和 7.0 自带的 tsc 撞名,另外重新导出了 6.0 的 API。typescript-eslint 这类工具通过 peer dependency 直接 import "typescript",所以官方推荐用 npm 别名,让 typescript 这个名字解析到 6.0:
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
}
这样 node_modules/typescript 里放的是 6.0,lint 和各种脚本照旧能 import。npx tsc 跑的则是 7.0。只做了第二行别名的话,手里就只剩 tsc6,这一点官方文章也特意提醒了。
嵌在别的语言里的场景更受限。发布文章写明,Vue、MDX、Astro、Svelte 这类工作流暂时还用不上 7,原因同样是没有稳定的编程接口。Volar 这种把 TypeScript 嵌进自己编译器和语言服务的工具,只能继续靠 6.0。Angular 项目可以拆开用:命令行用 7 的 tsc 做全项目查错,编辑器那边留在 6.0。官方说这是阶段性的问题,会和这些项目的维护者一起解决。
7.1 现在走到哪一步
7.1 目前还在 Beta。官方博客 10 月 20 日发了《Announcing TypeScript 7.1 Beta》,安装命令是 npm install -D typescript@beta。博客列表里还没有 RC 或正式版的文章,npm 上 latest 标签也还是 7.0。博客说接下来先出 RC,再出正式版,具体日子没定,这里就不猜了。
Beta 里的新 API 拆成了几个入口:
typescript/sync:同步的编译器客户端,带编译选项、类型检查器和 program 相关接口。typescript/async:基于 Promise 的同等版本。typescript/fs:按请求划分的完整文件系统和分层文件系统。typescript/ast、typescript/ast/is、typescript/ast/factory:节点类型和枚举、类型守卫、节点创建和更新函数。
照博客里的示例缩成几行,大概是这样:
import { API } from "typescript/sync";
using api = new API();
const parsed = api.parseCommandLine(["--strict", "--noEmit", "src/index.ts"]);
using program = api.createProgram(parsed.fileNames, parsed.options);
console.log(program.getSemanticDiagnostics().length);
注意这里用的是 using。API、Program 和快照都是 Disposable。创建这些对象时,TypeScript 会在 Go 和 JavaScript 两个运行时之间登记内存,光靠垃圾回收不够,Go 那一侧会泄漏。博客给了两条路:手动调用 api.close()、program.dispose() 这类方法,或者用 using 声明,离开作用域时自动释放。program 释放以后就不能再用了。习惯了 6.0 那种「拿到 program 随手扔」写法的脚本,迁过来时很容易在这里漏内存。
现在能做和先别做的
能做的:把项目里所有 import ... from "typescript" 的地方列出来,分清哪些只是 lint 在用,哪些是自己写的代码生成、检查脚本或 transformer。然后挑一个分支装上 7.1 Beta,把最简单的那个脚本按新入口改一遍,看看缺什么。想跟最新进度,可以换成 typescript@next 装每日构建。Beta 之后接口还可能调整,改过的脚本先别合进主干,留在分支上等正式版出来再对一遍。
先别做的:别急着拆掉 6.0 的别名,lint 插件跟进新 API 之前,这个别名还得留着。也别在主干上把 Beta 当正式依赖。博客没讲自定义 transformer 在新 API 里怎么接,这一块别默认能原样平移,等正式版文档出来再说。
你们项目里还有哪些工具离不开 6.0 的 API?