节目信息
TypeScript FM | 整理时间:2026 年 2 月 24 日
本期嘉宾:无特邀嘉宾(新闻资讯期)
主持人:Ayub(阿尤布)& Eric Ornheim(埃里克·奥恩海姆)
节目简介
本期是 TypeScript FM 的双周新闻汇总,补上了前两周的技术动态。最重磅的消息是 TypeScript 6.0 Beta 正式发布——这是当前版本迈向基于 Go 语言重写的 TypeScript 7.0 的过渡版本,严格模式将在 CLI 层面默认开启。此外还有 ESLint 10 发布、Deno Deploy 正式 GA、React Native 曝出 CVSS 9.8 高危漏洞等重要资讯,以及一个值得所有开发者警醒的安全教训:TypeScript 类型并不是运行时的安全防线。
核心话题讨论
话题 1:TypeScript 6.0 Beta——向 Go 迁移的倒计时
Ayub: 上周终于发布了 TypeScript 6.0 Beta,这里面有很多内容需要消化。简要总结一下:这仍然是一个过渡版本,连接着当前的 TypeScript 与未来基于 Go 语言实现的 TypeScript 7.0。
Eric: 最直接的变化就是严格模式了。现在在命令行直接运行 tsc 时,严格模式是默认开启的。以前你需要显式在 tsconfig.json 里设置 "strict": true,但现在 CLI 层面就默认严格了。
Ayub: 对,这有点反直觉的地方在于——如果你之前在 tsconfig 里没有配置 strict,CLI 命令行上反而会变成严格模式,这是个容易踩坑的细节。需要注意的是,你的 tsconfig 配置和 CLI 默认行为现在是分开管理的。
Eric: 另一个有趣的改动是关于”无 this 函数”(this-less functions)的上下文敏感度降低。简单说,TypeScript 做类型参数推断时,会优先跳过那些包含上下文敏感函数的参数,先从其他参数推断,推断失败了才回来检查这些函数。
Ayub: 如果你平时大量使用方法语法而不是箭头函数语法,这个改动会有帮助。博客文章里有代码示例,用语言描述很难说清,建议直接去看。本质上就是 TypeScript 对 this 关键字的感知更智能了,能更好地推断函数参数类型。
Eric: 还有一个实用的功能——支持以 # 号开头的子路径导入(Subpath Imports)。这个功能最初来自 Node.js,现在 TypeScript 也跟上了。你可以在 package.json 的 imports 字段里配置路径别名,用 #/ 来代替复杂的相对路径,比如 ../../ 这种。
Ayub: 对,这就像路径别名一样。以前 TypeScript 不支持用 # 号来定义根路径别名,现在 6.0 修复了这个问题。我在构建 Excalibur 时就遇到过这个问题,用 TS Go 构建时发现声明文件里类型的排序有差异。
💡 要点:TypeScript 6.0 Beta 是迈向 Go 版本 TypeScript 7.0 的过渡版本,引入了四大关键变化:CLI 严格模式默认开启、更智能的类型推断、子路径导入支持、以及新的
--stableTypeOrdering标志用于为迁移 7.0 做准备。升级前建议先用 Beta 版本测试,提前摸清哪些弃用项会影响你的代码库。
话题 2:TypeScript 6 新类型速览——Temporal、getOrInsert、RegExp.escape
Ayub: 6.0 里新增的类型也很丰富。最让我兴奋的是 Temporal API 终于有内置类型支持了!我们聊了很久的 Temporal 提案,现在它已经在除 Safari 之外的所有主流浏览器里实现了。
Eric: 是的,这个等了太久了。现在你可以通过设置 target: ESNext 或者 lib: ESNext 在 TypeScript 代码里直接使用 Temporal API,或者更精细地导入 lib temporal.es.next。
Ayub: 还有 Map 和 WeakMap 的 getOrInsert 方法——这就是业界俗称的 “upsert”(检查键是否存在,不存在就插入默认值)。这种操作太常见了,常见到已经写进了 ECMAScript 规范。还有 getOrInsertComputed,适用于默认值计算成本较高的情况,支持惰性计算。
Eric: 另一个是 RegExp.escape——当你需要在正则表达式字符串中替换某个子表达式时,可以通过这个方法转义特殊字符(比如 +、?、* 等通配符),而不用担心不小心引入正则安全漏洞。之前我们处理 MySQL 转义时就是类似的思路。
Ayub: 还有一个对实践很有用的变化——lib.dom.d.ts 现在完整包含了 DOM Iterable 和 DOM AsyncIterable。以前你需要手动引入这个库,现在自动就有了。
💡 要点:TypeScript 6.0 新增的类型支持覆盖了多个期待已久的 JavaScript API:Temporal(除 Safari 外全线上线)、Map/WeakMap 的
getOrInsert、RegExp.escape以及 DOM 可迭代类型。这些都是真实开发中高频使用的能力。
话题 3:ESLint 10 发布——ESLintRC 彻底退场
Eric: 这次 ESLint 发布了大版本 10!能达到 10.0 版本的项目并不多,这是个值得庆祝的里程碑。
Ayub: 最直接影响你的变化是配置文件格式。如果你现在还在使用 .eslintrc 文件,在 ESLint 10 中已经彻底移除了。ESLint 9 开始推广的扁平化配置(Flat Config,即 eslint.config.js)现在是唯一方式。
Eric: 另外,Node.js 的支持版本也提高了——低于 20.19 的版本,整个 21.x 和 23.x 系列都不再支持。Node 24.x 是当前的 LTS 版本,如果你还在用老版本,是时候升级了。
Ayub: 还有一个需要注意的:eslint:recommended 规则列表更新了,新增了三条默认启用的规则:no-unused-vars(禁止未使用变量)、no-useless-assignment(禁止无用赋值)、以及 no-inner-declarations(保留捕获的错误)。这些规则默认开启后可能会让你的代码飘满红线。
💡 要点:升级 ESLint 10 前必须完成三件事:迁移到 Flat Config 格式、检查 Node.js 版本兼容性、处理新增默认规则带来的代码警告。官方提供了详细的迁移指南。
话题 4:Deno Deploy 正式 GA——内置 ngrok 和 OpenTelemetry
Ayub: Deno Deploy 正式从预览阶段发布了,不再是 Preview 了!虽然叫 Dino Deploy,但它支持所有主流 JavaScript 框架——Next.js、Astro、Fresh 等,会自动检测你用的框架并运行对应的构建命令。
Eric: 感觉很像 Netlify 的模式,只需把代码仓库指向他们的无服务器云主机,剩下的自动处理。他们还新增了基于 Dino Sandbox 的安全即时计算功能,可以通过编程方式创建小型 Linux 虚拟机,能在 1 秒内启动。
Ayub: 这个 Sandbox 对于处理 LLM 生成的代码特别有用——你可以把不可信的代码放进沙箱运行,完全隔离于当前进程,防止它访问你的秘密或环境变量。用户上传文件的场景也很适用。
Eric: 我最喜欢的是他们内置了一流的可观测性支持,直接在应用中自动完成 OpenTelemetry 仪器化。默认就会捕获控制台日志、fetch 请求、HTTP 事件、V8 事件、垃圾回收和 IO 操作,而且日志会自动关联到请求。现在没有 OpenTelemetry 真不知道怎么做事。
Ayub: 还有一个特别实用的功能——本地开发隧道(Tunnel)。在命令行加上 --tunnel 标志,就能自动从 Deno Deploy 拉取环境变量,生成公开可分享的链接,并将遥测数据发回 Deno Deploy。这几乎就是内置的 ngrok!对于做移动端测试特别方便,不用再绕 IP 地址了。
Eric: 对,做 Webhook 开发时也很好用,不用为了测试就部署到公开端点。不过要注意这个链接是公开的,如果涉及敏感数据要配合访问控制(比如 SSO)一起使用。
Ayub: 定价也很有竞争力——免费计划每月 100 万次请求、100GB 出站流量、15 个 CPU 小时;专业版每月 20 美元,提供 500 万次请求、200GB 带宽、40 小时 CPU 时间。还支持 PostgreSQL,通过与 Prisma 合作,可以直接在控制面板免费创建数据库,有点像 Supabase 的竞争方案。
💡 要点:Deno Deploy GA 版本的亮点是:支持全栈框架自动检测部署、LLM 代码沙箱隔离、内置 OpenTelemetry 可观测性、类 ngrok 的本地开发隧道,以及 Prisma 加持的 PostgreSQL 支持。免费计划慷慨,是 Netlify 的有力竞争者。
话题 5:React Native 高危漏洞——CVSS 9.8 的”Metro for Shell”
Eric: 来说一个严峻的安全警报——React Native 出现了一个严重的远程代码执行漏洞,代号 “Metro for Shell”,CVSS 评分 9.8(满分 10 分)。
Ayub: 这意味着远程未认证攻击者可以在底层主机上执行任意操作系统命令。攻击者利用这个漏洞分发了经过 Base64 编码的 PowerShell 脚本,这是一种非常常见的恶意软件分发方式。
Eric: 漏洞的根本原因是:Metro 开发服务器默认会绑定到外部接口,而不是仅 localhost。这是非常严重的安全设计问题。暴露的接口存在注入漏洞,允许未认证的网络攻击者直接发送 POST 请求。如果你的网络里有被攻陷的 IoT 设备,攻击者就能扫描开放的开发端口,直接投放恶意软件。
Ayub: 如果你是 React Native 开发者,立刻升级你的 React Native CLI。
💡 要点:Metro 开发服务器默认绑定外部接口是这个漏洞的核心问题。开发工具的安全配置不容忽视,绑定 localhost 应当是默认行为而非可选项。
话题 6:TypeScript 类型不是安全功能——来自真实漏洞的教训
Ayub: 这是本期最值得深思的内容。安全研究员 Fatih Çelik 在 Nation 平台(一个类似 Zapier 的低代码自动化工具)发现了多个远程代码执行漏洞,而且漏洞的根源与 TypeScript 的使用方式有直接关系。
Eric: Nation 是开源的,所以他能直接看到源码。他发现的漏洞链是这样的:用户可以在工作流里输入 JavaScript 表达式,而系统没有对这类输入做充分验证。通过向上追溯构造函数链,可以创建一个新函数来调用 child_process,从而实现远程代码执行。
Ayub: Nation 的团队尝试做了一些修补,比如拒绝包含 String 构造函数的调用。但 JavaScript 是动态语言,你可以通过字符串的 charCodeAt 动态构建任意字符串来绕过字符串匹配检查。这种基于拒绝列表的缓解措施往往不可靠。
Eric: 这里有个关键的 TypeScript 教训:代码接收了一个 unknown 类型的参数,这是正确的——TypeScript 层面的类型标注做对了。但随后他们将其强制转换(cast)为字符串,而不是验证它的运行时类型是否真的是字符串。这个区别很致命。
Ayub: 类型断言(type cast)和类型验证(type guard)是完全不同的两件事。正确的做法是:if (typeof input === 'string') { ... },而不是 String(input)。后者会把任何值都转成字符串,完全绕过了类型检查的意图。
Eric: 核心教训就是:TypeScript 类型是开发阶段的工具,不是运行时的安全保障。类型在编译后被擦除,运行时什么都不剩。边界校验必须在运行时显式完成,这一点永远无法被 TypeScript 类型所替代。
💡 思考:这个漏洞展示了一个经典的安全误区——把编译时的类型系统当成运行时的安全屏障。
unknown→as string的写法感觉”类型安全”,但实际上绕过了所有运行时校验。真正的边界安全来自 Zod、运行时类型守卫等工具,而不是 TypeScript 类型标注。
话题 7:社区速报——ElectroBun、Tabularis 与 JSDoc 类型技巧
Ayub: 快速过一下本期的库和工具更新。ElectroBun——基于 Bun 运行时的 Electron 框架,有个很有趣的特性:更新时不需要下载完整的二进制文件,只下载源码的差异文件,相当于增量更新。理论上运行更快、内存占用更低。我最近做了一个 Electron 应用,编译出来的二进制文件高达 178MB,如果能有轻量化方案就好了。
Eric: Tabularis 是一款面向开发者的轻量级数据库管理工具,支持 MySQL、PostgreSQL、SQLite,基于 Tauri 和 React 构建。最有趣的是它内置了 MCP 服务器,可以直接让 AI 助手查询和操作你的数据库结构——AI 原生的数据库工具。
Ayub: 还有一个很实用的 JSDoc 技巧——你可以用 JSDoc 把 TypeScript 类型导入到普通的 JavaScript 文件里,完全不需要编译步骤。Eric 在他的浏览器扩展里就是这么做的,因为浏览器扩展编译成其他语言会很麻烦,直接用 JS + JSDoc 类型导入是个好选择。
Eric: Handy 是一款免费开源的离线语音转文字工具,基于 Tauri 构建,前端用 React + TypeScript,后端用 Rust,本地运行 Whisper 模型。好处是不需要联网,隐私友好。任何输入框都能用——即使应用本身不支持语音输入,也可以通过 Handy 来实现。
💡 要点:ElectroBun(轻量化 Electron)、Tabularis(AI 原生数据库工具,内置 MCP 服务器)、以及 JSDoc 类型导入技巧,是本期值得关注的三个实用工具。
📚 技术术语
- TypeScript 7.0 (Go 版本): 微软正在用 Go 语言完全重写 TypeScript 编译器,目标是大幅提升编译速度。TypeScript 6.0 是过渡版本,帮助开发者逐步迁移。
- Flat Config(扁平化配置): ESLint 9+ 引入的新配置格式(
eslint.config.js),废弃了传统的.eslintrc.*文件,ESLint 10 中已彻底移除旧格式。 - Temporal API: 下一代 JavaScript 日期时间 API,解决了
Date对象的众多历史遗留问题,支持时区和日历,已进入 TC39 第三阶段。 - OpenTelemetry: 分布式追踪的开放标准,用于收集和导出遥测数据(日志、指标、追踪),是现代可观测性基础设施的核心。
- Metro 开发服务器: React Native 的 JavaScript 打包工具和开发服务器,此次漏洞的根源是其默认绑定到外部网络接口。
- CVSS: 通用漏洞评分系统(Common Vulnerability Scoring System),满分 10 分,9.8 属于超高危级别。
- MCP 服务器: Model Context Protocol 服务器,允许 AI 模型以结构化方式访问外部工具和数据源。
- getOrInsert: Map/WeakMap 新增方法,原子性地检查键是否存在并在不存在时插入默认值,等同于数据库中的 “upsert” 操作。
💬 金句摘录
“TypeScript 类型是开发阶段的工具,不是运行时的安全保障。” —— Eric
“TypeScript 6 是向 TypeScript 7 过渡的版本,你可以选择忽略这些弃用提示,但迁移到 7.0 时它们会让你的代码库中断。” —— Ayub
“Metro 开发服务器默认绑定到外部接口,这是非常严重的安全问题。” —— Eric
“现在没有 OpenTelemetry 真不知道怎么做事。” —— Eric
🤔 思考与启发
本期节目展现了 TypeScript 生态正处于一个关键转折点的多维度思考:
- 类型系统与运行时安全的边界: Nation 漏洞事件是一堂价值百万的公开课——TypeScript 类型在编译后消失,运行时的世界由 JavaScript 控制。
unknown类型标注只是开发者的意图声明,不是运行时的保护墙。边界数据(用户输入、外部 API 返回)永远需要运行时校验,typeof、instanceof或 Zod 这类验证库不可或缺。 - 从 TypeScript 6 到 7 的准备窗口: TypeScript 团队给了开发者一个明确的过渡期。现在就应该把项目升级到 6.0 Beta,看看哪些弃用警告会出现,趁早处理而不是等 7.0 发布后措手不及。特别需要关注的是
--stableTypeOrdering标志和模块解析配置。 - 开发服务器的安全边界: Metro 漏洞提醒我们:开发工具默认应该绑定 localhost 而不是外部接口。这不只是 React Native 的问题,任何开发服务器(Vite、Webpack Dev Server 等)都需要审视其默认网络配置,尤其是在公共 WiFi 或共享网络环境下工作时。
延伸思考: 当 TypeScript 7.0 完全切换到 Go 编译器时,现有的工具链(ESLint TypeScript 插件、ts-node、tsc-watch 等)需要多久才能适配?社区生态的迁移成本会比 TypeScript 本身的迁移成本更高吗?
