Node.js v26.0.0 文档
- Node.js v26.0.0
- 目录
- 索引
- 关于本文档
- 用法与示例
- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲区
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入器 API
- 子进程
- 集群
- 命令行选项
- 控制台
- 加密
- 调试器
- 已弃用的 API
- 诊断通道
- DNS
- 域
- 环境变量
- 错误
- 事件
- 文件系统
- 全局对象
- HTTP
- HTTP/2
- HTTPS
- 检查器
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:moduleAPI - 模块:包
- 模块:TypeScript
- 网络
- 可迭代流 API
- 操作系统
- 路径
- 性能钩子
- 权限
- 进程
- Punycode
- 查询字符串
- 逐行读取
- REPL
- 报告
- 单一可执行文件应用
- SQLite
- 流
- 字符串解码器
- 测试运行器
- 定时器
- TLS/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用工具
- V8
- 虚拟机
- WASI
- Web Crypto API
- Web Streams API
- 工作线程
- Zlib
- Zlib 可迭代压缩
- 其他版本
- 选项
模块:TypeScript#
稳定性:2 - 稳定
启用#
在 Node.js 中启用运行时 TypeScript 支持有两种方式:
完整的 TypeScript 支持#
若要使用完整支持所有 TypeScript 特性(包括 tsconfig.json)的 TypeScript,可以使用第三方软件包。以下说明以 tsx 为例,但还有许多其他类似的库可供使用。
-
使用项目所用的包管理器将该包安装为开发依赖。例如,使用
npm:npm install --save-dev tsx -
然后,可以通过以下方式运行 TypeScript 代码:
npx tsx your-file.ts或者,也可以通过以下方式使用
node运行:node --import=tsx your-file.ts
类型剥离#
默认情况下,Node.js 会执行仅包含可擦除 TypeScript 语法的 TypeScript 文件。Node.js 会将 TypeScript 语法替换为空格,且不执行类型检查。要禁用此功能,请使用标志 --no-strip-types。
Node.js 会忽略 tsconfig.json 文件,因此依赖于 tsconfig.json 设置的功能(例如路径映射或将较新的 JavaScript 语法转换为旧标准)被有意不支持。要获得完整的 TypeScript 支持,请参阅完整的 TypeScript 支持。
类型剥离功能旨在实现轻量化。通过有意不支持需要 JavaScript 代码生成的语法,并将内联类型替换为空格,Node.js 可以在无需源映射的情况下运行 TypeScript 代码。
类型剥离与大多数版本的 TypeScript 兼容,但我们建议使用 5.8 或更新版本,并配置以下 tsconfig.json 设置:
{
"compilerOptions": {
"noEmit": true, // Optional - see note below
"target": "esnext",
"module": "nodenext",
"rewriteRelativeImportExtensions": true,
"erasableSyntaxOnly": true,
"verbatimModuleSyntax": true
}
}
如果你打算仅执行 *.ts 文件(例如构建脚本),请使用 noEmit 选项。如果你打算分发 *.js 文件,则无需此标志。
确定模块系统#
Node.js 在 TypeScript 文件中同时支持 CommonJS 和 ES 模块语法。Node.js 不会在不同模块系统之间进行转换;如果你希望代码作为 ES 模块运行,则必须使用 import 和 export 语法;如果希望代码作为 CommonJS 运行,则必须使用 require 和 module.exports。
.ts文件的模块系统确定方式与.js文件相同。要使用import和export语法,请在最近的父级package.json中添加"type": "module"。.mts文件将始终作为 ES 模块运行,类似于.mjs文件。.cts文件将始终作为 CommonJS 模块运行,类似于.cjs文件。- 不支持
.tsx文件。
与 JavaScript 文件一样,在 import 语句和 import() 表达式中,文件扩展名是强制性的:应使用 import './file.ts',而不是 import './file'。出于向后兼容性考虑,在 require() 调用中文件扩展名同样是强制性的:应使用 require('./file.ts'),而不是 require('./file'),这类似于在 CommonJS 文件中 require 调用强制要求 .cjs 扩展名。
tsconfig.json 中的 allowImportingTsExtensions 选项允许 TypeScript 编译器 tsc 对包含 .ts 扩展名的 import 说明符文件进行类型检查。
TypeScript 特性#
由于 Node.js 仅移除内联类型,任何涉及将 TypeScript 语法替换为新 JavaScript 语法的 TypeScript 特性都会报错。
最显著的需要转换的特性包括:
Enum(枚举)声明- 包含运行时代码的
namespace(命名空间) - 参数属性(parameter properties)
- 导入别名(import aliases)
支持不包含运行时代码的 namespace。以下示例可以正常工作:
// This namespace is exporting a type
namespace TypeOnly {
export type A = string;
}
这会导致 ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX 错误:
// This namespace is exporting a value
namespace A {
export let x = 1
}
由于装饰器目前是 TC39 Stage 3 提案,它们不会被转换,并将导致解析器错误。Node.js 不提供 polyfill,因此在 JavaScript 原生支持装饰器之前,它不会支持该特性。
此外,Node.js 不会读取 tsconfig.json 文件,也不支持依赖于 tsconfig.json 设置的特性,例如路径映射或将较新的 JavaScript 语法转换为旧标准。
在没有 type 关键字的情况下导入类型#
由于类型剥离的本质,type 关键字对于正确剥离类型导入是必要的。如果没有 type 关键字,Node.js 会将导入视为值导入,这会导致运行时错误。可以使用 tsconfig 选项 verbatimModuleSyntax 来匹配此行为。
此示例可以正常工作:
import type { Type1, Type2 } from './module.ts';
import { fn, type FnParams } from './fn.ts';
这会导致运行时错误:
import { Type1, Type2 } from './module.ts';
import { fn, FnParams } from './fn.ts';
非文件形式的输入#
可以在 --eval 和 STDIN 中启用类型剥离。模块系统将由 --input-type 决定,就像 JavaScript 一样。
REPL、--check 和 inspect 不支持 TypeScript 语法。
源映射#
由于内联类型被替换为空格,因此对于堆栈跟踪中的正确行号,源映射是不必要的;Node.js 也不会生成它们。
依赖项中的类型剥离#
为了劝阻包作者发布用 TypeScript 编写的包,Node.js 拒绝处理 node_modules 路径下的文件夹中的 TypeScript 文件。
路径别名#
tsconfig "paths" 不会被转换,因此会产生错误。目前可用的最接近的特性是子路径导入(subpath imports),但限制是它们必须以 # 开头。