模块:TypeScript
[历史]
版本 | 变更 |
---|---|
v22.7.0 | 添加了 --experimental-transform-types 标记。 |
启用
在 Node.js 中启用运行时 TypeScript 支持有两种方法:
完全 TypeScript 支持
要使用对所有 TypeScript 特性(包括 tsconfig.json
)都提供完全支持的 TypeScript,您可以使用第三方包。这些说明使用 tsx
作为示例,但还有许多其他类似的库可用。
类型去除
新增于:v22.6.0
标记 --experimental-strip-types
使 Node.js 能够运行 TypeScript 文件。默认情况下,Node.js 只会执行不包含需要转换的 TypeScript 特性(例如枚举或命名空间)的文件。Node.js 将用空格替换内联类型注解,并且不执行类型检查。要启用此类特性的转换,请使用标记 --experimental-transform-types
。故意不支持依赖于 tsconfig.json
中设置的 TypeScript 特性,例如路径或将较新的 JavaScript 语法转换为较旧的标准。要获得完全的 TypeScript 支持,请参阅 完全 TypeScript 支持。
类型去除功能旨在轻量化。通过故意不支持需要 JavaScript 代码生成的语法,并用空格替换内联类型,Node.js 可以在无需源映射的情况下运行 TypeScript 代码。
类型去除适用于大多数版本的 TypeScript,但我们建议使用 5.7 或更高版本,并使用以下 tsconfig.json
设置:
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": true,
"verbatimModuleSyntax": true
}
}
模块系统确定
Node.js 支持 TypeScript 文件中的 CommonJS 和 ES 模块 语法。Node.js 不会将一种模块系统转换为另一种;如果希望代码作为 ES 模块运行,则必须使用 import
和 export
语法;如果希望代码作为 CommonJS 运行,则必须使用 require
和 module.exports
。
.ts
文件的模块系统确定方式与.js
文件相同。[/api/packages#determining-module-system] 若要使用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')
,类似于 .cjs
扩展名在 CommonJS 文件的 require
调用中是必需的。
tsconfig.json
选项 allowImportingTsExtensions
将允许 TypeScript 编译器 tsc
检查包含 .ts
扩展名的 import
说明符的文件类型。
TypeScript 特性
由于 Node.js 只移除内联类型,任何涉及使用新的 JavaScript 语法 替换 TypeScript 语法的 TypeScript 特性都会报错,除非传递标志 --experimental-transform-types
。
需要转换的最显著特性包括:
枚举
命名空间
传统模块
- 参数属性
由于装饰器目前是 TC39 第三阶段提案,并且很快就会得到 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
启用类型去除。模块系统将由 --input-type
确定,就像 JavaScript 一样。
TypeScript 语法在 REPL、标准输入、--print
、--check
和 inspect
中不受支持。
源映射
由于内联类型被空格替换,因此源映射对于堆栈跟踪中的正确行号是不必要的;Node.js 不会生成它们。启用 --experimental-transform-types
时,会默认启用源映射。
依赖项中的类型去除
为了阻止包作者发布用 TypeScript 编写的包,Node.js 默认情况下会拒绝处理 node_modules
路径下文件夹内的 TypeScript 文件。
路径别名
tsconfig
"paths" 不会被转换,因此会产生错误。最接近的可用功能是 子路径导入,但其限制是它们必须以 #
开头。