Node 刚刚添加了 TypeScript 支持。这对 Deno 意味着什么?
Node.js 最近在 22.6 版本(并在 23.6 版本中稳定)中添加了原生的 TypeScript 支持,这是一个令人欢迎的增强,简化了 TypeScript 用户的设置。这在社区内引发了关于 Node 的新功能与 Deno 现有的 TypeScript 集成相比如何的问题。
在这篇文章中,我们将探讨 Node 的 TypeScript 支持,并提供与 Deno 方法的清晰比较。
Node 中的 TypeScript
TypeScript 为 JavaScript 添加了类型,有助于在项目增长时构建你的代码。它主要处理两个任务:
- 类型检查: 确保你的变量与声明的类型匹配。
- 类型剥离: 将 TypeScript 转译为纯 JavaScript,可由浏览器和运行时执行。
Node 22.6.0 引入了内置的 TypeScript 支持,允许通过 --experimental-strip-types
标志自动进行类型剥离。此功能在 Node 23.6 中得到稳定,无需额外的标志即可直接执行 (node foo.ts
)。
Node 的 TypeScript 支持将类型注解替换为空格,从而生成有效的 JavaScript:
function sum(a: number, b: number): number {
return a + b;
}
sum(5, 10);
function sum(a , b ) {
return a + b;
}
sum(5, 10);
这实际上是将以前由 ts-node
提供的功能直接集成到 Node 中,简化了 TypeScript 的执行。
然而,存在一些限制:
- 没有内置的类型检查: 仍然需要像
tsc
这样的外部工具。 - 不支持 JSX 或 TSX: Node 处理
.ts
、.mts
和.cts
,但 React (.tsx
) 和 JSX 项目仍然需要外部转译器或打包器,例如esbuild
、Babel 或tsc
。 - 手动管理
tsconfig.json
: 类型检查仍然依赖于通过tsconfig.json
进行的外部配置。
以上是 Node 中 TypeScript 的概述——让我们看看 Deno 如何处理这些方面。
Deno 中的 TypeScript
Deno 通过提供一个具有完全集成的 TypeScript 工具链的单个可执行文件来简化 Web 编程。这种方法以最少的配置提供 TypeScript 的优势,从而简化了测试、格式化和编译工作流程。
Deno 的 TypeScript 集成包括三个主要部分:
- 执行: Google 的 V8 引擎,它执行 JavaScript,但不能直接执行 TypeScript。
- 类型检查: Microsoft 的 TypeScript 编译器(用 JavaScript 实现)在内部捆绑。
- 类型剥离: SWC,一个由 Kang Dong Yoon (강동윤) 用 Rust 构建的高性能解析器,高效地剥离类型,而无需运行 JavaScript。
那 tsconfig.json
呢?
Deno 强调零配置开发,以避免配置过载。它提供了适用于大多数场景的合理默认值(详情请点击此处)。如果需要自定义选项,你可以轻松地在 deno.json
中使用 compilerOptions
,或者指定你自己的 tsconfig.json
:
deno -c tsconfig.json main.ts
在 CI 中使用 deno check
进行类型检查
运行 deno check
可以快速识别类型错误,无论是在本地还是远程:
deno check
deno check main.ts
deno check jsr:@std/http/file-server
deno check --all
deno check --doc
deno check --doc-only
使用 LSP 实现类型感知的工具提示、错误等
当使用 Deno 的语言服务器 (LSP),特别是与像 VSCode 这样的编辑器一起使用时,你将获得即时的类型感知反馈和 linting。
VSCode 中 JSR 依赖的实时类型检查。无需配置。
显示文档的悬停工具提示。
deno repl
和 deno jupyter
中的 TypeScript
你可以在 Deno 的 REPL 或 Jupyter Notebooks 中直接运行 TypeScript:
$ deno
Deno 2.2.2
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
> const sum = function(a: number, b: number): number { return a + b };
undefined
> sum(5, 10)
15
(注意:REPL 将类型视为注释;没有实时检查。)
无需转译即可分发 TypeScript
Deno 支持直接分发 TypeScript 模块,无需转译步骤和单独的 .d.ts
文件。
JSR 注册表 利用了这一点,促进了无缝的 TypeScript 分发,而不会损失清晰度或可读性:
import { encodeBase64 } from "jsr:@std/encoding@1";
借助 JSR,调试仍然清晰明了——堆栈跟踪和源码导航直接链接到原始 TypeScript 代码。
TypeScript 和 npm
Deno 通过 package.json
或 npm:
说明符导入 npm 模块,并通过 .d.ts
文件提供完整的类型检查支持。对于没有类型的包,请使用 @ts-types
pragma:
import express from "npm:express";
Deno 工具链中的 TypeScript 支持
Deno 在其整个工具链中广泛集成了 TypeScript:
deno fmt
: 格式化 TypeScript。deno compile
: 将 TypeScript 编译为可执行文件。deno doc
: 直接从 TypeScript 生成文档。deno lint
: 内置的 TypeScript linting 规则。
此外,.tsx
和 .jsx
支持使 React 或 Preact 无缝衔接。