TypeScript 已经不再是原来的 TypeScript 了...

BBetter Stack
Computing/SoftwareInternet Technology

Transcript

00:00:00TypeScript 发布了第 7 版本的候选版本,这将是
00:00:04TypeScript 不再是原来的 TypeScript 的版本。如果你还没关注,他们一直在致力于重写
00:00:07TypeScript 编译器,从 TypeScript 自身改用 Go 编写,显然结果是速度提升了 10 倍。
00:00:12他们预计下个月发布 TypeScript 7,所以让我们看看实际有哪些变化,
00:00:17它的速度有多快,以及在安装前是否需要了解任何重大变更。
00:00:26如果你错过了关于他们移植到 Go 的消息,他们其实大约在一年前就开始了,
00:00:29简而言之,他们意识到 JavaScript 从未被设计用于处理
00:00:34类型检查器这种繁重的 CPU 密集型工作,所以他们开始将其用 Go 重写,并取得了巨大的早期成功。他们实际上是从
00:00:39基本上逐行移植现有的 TypeScript 实现开始的,所以类型
00:00:44检查逻辑在结构上完全相同,行为也一致,你甚至可以看到一些
00:00:48函数除了语言不同之外几乎一模一样。我敢肯定这还是在
00:00:52你不能直接把代码库丢给 Claude 说“帮我迁移到任意语言”之前发生的。
00:00:56我说得就是你,Bun。移植的结果说明了一切。这里我有一个
00:01:00Playwright 仓库,如果我使用旧版本的 TypeScript 进行类型检查,我们可以看到这
00:01:04大约需要 6 秒才能完成,它处理了 1400 个文件和五十万行
00:01:08代码。如果我现在切换到候选发布版,除了这个命令之外什么都不改,
00:01:12总共只花了 0.87 秒。这是一个巨大的提升。它还找出了完全相同数量的
00:01:18错误,相同的错误,它经过了相同的文件和所有的代码行,所以它的工作方式与
00:01:23TypeScript 6 完全一样。Go 的原生代码对于这种任务来说,本质上比 JavaScript 更快,
00:01:27而且它还允许他们使用共享内存并行处理,所以 JavaScript 编译器
00:01:32是单线程的,而 Go 可以将类型检查分散到多个核心上同时进行。在 TypeScript
00:01:377 中,你实际上可以通过一个标志强制其单线程运行,也许你正在进行一些调试,
00:01:41或者是在资源有限的机器上运行。如果我在 Playwright 代码库中
00:01:46使用 TypeScript 7 执行此操作,我们可以看到单线程时大约需要 2 秒,这
00:01:50仍然比之前快了三倍。谈到并行运行,他们还引入了
00:01:54一个新的“checkers”标志,它实际上让你设置多少个类型检查器工作者可以并行运行,
00:01:58默认值为 4。如果你拥有大量的 CPU 核心,增加这个值可以加速大型代码库的构建,
00:02:03但它会以额外的内存使用为代价。如果我在这个 Playwright 仓库中将 checkers
00:02:08设置为 8(默认值的两倍),它确实看起来又节省了
00:02:12三分之一的时间。还有一个新的“builders”标志,用于并行化项目引用构建,即同时构建
00:02:16多个项目。这个标志让你控制可以同时运行的并行构建器的数量,
00:02:20值得注意的是,如果你将此与我们刚刚看到的 checkers 结合使用,假设
00:02:24你各有 4 个,这意味着你现在可以同时运行多达 16 个类型检查器。此外,
00:02:29除了原生代码更改和并行处理,TypeScript 7 的另一个重大重写是它的监视模式(watch mode)。
00:02:34当他们移植到 Go 时,这其实更棘手一些,因为标准库不提供
00:02:38内置的文件监视 API,而他们尝试的第三方库在稳定性、性能
00:02:43和跨平台支持方面都有问题。所以团队实际上研究了 Parcel 打包工具的
00:02:47文件监视器,微软在 VS Code 中也使用过它,但由于它是用 C++ 编写的,他们也
00:02:53必须将所需的部分移植到 Go 中。好消息是,他们确实
00:02:57完成了所有工作,而且看起来运行得非常顺利,比以前更好。接下来,由于这是一个
00:03:01主要版本升级,你可能预期会有很多重大变更,特别是因为这是一个巨大的
00:03:05重写,但我认为实际上并没有。如果你是从 TypeScript 6 升级到 7,
00:03:10如果你想从 5 升级到 7,那会有相当多的变更。所以他们似乎建议你
00:03:14先升级到 6,确保一切正常工作,然后再升级到 7 应该就不会有任何问题。一些
00:03:19TypeScript 6 的重大变更包括移除 ES5 目标、移除 baseUrl,并弃用了模块
00:03:24系统 AMD、UMD 和 SystemJS。他们还将 strict 默认设为 true,将 module 默认设为 esnext,
00:03:31target 默认设为紧接在 esnext 之前的当前稳定 ECMAScript 版本。这
00:03:36基本上是抛弃过去,实现 TypeScript 现代化,我真的很喜欢这一点,因为
00:03:40有时候尝试在每个版本中支持遗留项目,真的会拖慢工具的
00:03:45进步。查看这篇博客文章的其余部分,实际上似乎只有一项
00:03:49与 TypeScript 语言本身相关的新功能或变更,就是模板字面量
00:03:53类型现在保留 Unicode 码点。本质上,在 TypeScript 7 之前,TypeScript 实际上是按照 UTF-16 代码
00:03:59单元进行分割的,所以它最终会把一个 emoji 表情符号一分为二,导致你最终得到这些奇怪的头部和
00:04:04尾部类型。而在 TypeScript 7 中,它实际上是按整个码点进行分割,也就是完整的字符,
00:04:09所以现在 emoji 被完整保留了,分割也和你预想的一样。我
00:04:13真的很佩服如果在你们使用 TypeScript 的过程中曾遇到过这个问题的人。
00:04:18总而言之,这些更改应该会让任何使用 TypeScript 的东西感觉快得多,比如编辑器中的
00:04:22TypeScript,特别是对于大型项目。稳定版本预计在大约一个月内发布,
00:04:27但是一个稳定的编程 API,也就是工具作者用来在编译器之上进行开发的东西,
00:04:32将在 7.1 版本中发布。正因如此,还有一个兼容性包,所以你可以
00:04:36并排运行 TypeScript 6 和 7 而不会产生冲突。告诉我你对这一切的看法,
00:04:41我很好奇你是否曾经觉得 TypeScript 很慢,请在评论区告诉
00:04:44我。在你们去评论的同时,记得订阅,我们下期视频再见。

Key Takeaway

TypeScript 7 通过迁移至 Go 语言并启用多核并行处理,在保持类型检查逻辑一致的前提下,实现了约 7 倍的性能提升。

Highlights

  • TypeScript 7 使用 Go 语言重写编译器,处理 1400 个文件和 50 万行代码的类型检查耗时从 6 秒缩短至 0.87 秒。

  • Go 语言的原生并行处理能力允许 TypeScript 7 利用多核心 CPU 同时进行类型检查,不再局限于单线程。

  • 通过 checkers 标志可设置并行工作者数量,增加该值能进一步缩短大型代码库的构建时间。

  • TypeScript 7 的监视模式(watch mode)通过移植 Parcel 的文件监视器实现,在稳定性与性能上超过旧版本。

  • 模板字面量类型在 TypeScript 7 中改为按完整 Unicode 码点分割,彻底解决了 emoji 表情符号被错误拆分的问题。

  • 升级至 TypeScript 7 建议先迁移至 TypeScript 6,以处理移除了 ES5 目标、baseUrl 等遗留配置的重大变更。

Timeline

编译器重写与性能提升

  • TypeScript 7 使用 Go 语言重写了编译器核心逻辑。
  • 类型检查速度在相同代码库下提升了约 7 倍。
  • Go 的原生多线程架构解决了 JavaScript 单线程处理类型检查的瓶颈。

开发团队意识到 JavaScript 不适合高负载的 CPU 密集型任务,因此将编译器移植到 Go 语言。在 Playwright 代码库的实测中,旧版 TypeScript 需要 6 秒的检查任务,在候选版本中仅耗时 0.87 秒。这种移植保持了逻辑结构的一致性,确保了类型检查结果的精确性。

并行处理机制

  • checkers 标志允许并行运行多个类型检查器工作者,默认值为 4。
  • builders 标志支持并行构建项目引用,允许多个项目同时编译。
  • 结合 checkers 与 builders 设置,可同时并行运行最多 16 个类型检查任务。

TypeScript 7 支持通过配置标志调整并发程度。增加 checkers 的数量可以利用更多 CPU 核心,从而显著减少大型项目的等待时间,代价是内存占用增加。在 Playwright 仓库中,将 checkers 设置为 8 可额外节省三分之一的构建时间。

监视模式与重大变更

  • 监视模式通过移植 Parcel 的 C++ 文件监视器逻辑实现,提升了跨平台稳定性。
  • 升级至 7 版本前需先完成至 TypeScript 6 的迁移,以适配移除 ES5、baseUrl 等遗留特性。
  • 模板字面量类型现在按 Unicode 码点分割,完整保留 emoji 表情。

监视模式在重写过程中克服了原生 API 的限制。为了实现现代化,TypeScript 6 移除了 ES5 目标、baseUrl 以及 AMD/UMD 等模块系统,并默认启用了严格模式。模板字面量处理的改进修复了以往将 emoji 拆分为半个字符的缺陷,实现了更精确的字符串类型处理。

Community Posts

No posts yet. Be the first to write about this video!

Write about this video