Node.js v22.22.0 文档


模块:TypeScript#>

【Modules: TypeScript】

稳定性: 1.2 - 发布候选版

启用#>

【Enabling】

有两种方法可以在 Node.js 中启用运行时 TypeScript 支持:

【There are two ways to enable runtime TypeScript support in Node.js:】

  1. 对于 TypeScript 的所有语法和功能,包括使用任何版本的 TypeScript,请使用第三方包。
  2. 对于轻量级支持,你可以使用内置的 类型剥离 支持。

完全支持 TypeScript#>

【Full TypeScript support】

要使用 TypeScript 并完全支持所有 TypeScript 功能,包括 tsconfig.json,你可以使用第三方包。这些说明以 tsx 为例,但还有许多其他类似的库可用。

【To use TypeScript with full support for all TypeScript features, including tsconfig.json, you can use a third-party package. These instructions use tsx as an example but there are many other similar libraries available.】

  1. 使用你项目中使用的任何包管理器将该包安装为开发依赖。例如,使用 npm

    npm install --save-dev tsx 
  2. 然后你可以通过以下方式运行你的 TypeScript 代码:

    npx tsx your-file.ts 

    或者,你也可以通过以下方式使用 node 运行:

    node --import=tsx your-file.ts 

类型剥离#>

【Type stripping】

--no-experimental-strip-types 标志会阻止 Node.js 运行 TypeScript 文件。默认情况下,Node.js 只会执行不包含需要转换的 TypeScript 功能(如枚举)的文件。Node.js 会将内联类型注释替换为空格,并且不会进行类型检查。要启用这些功能的转换,请使用 --experimental-transform-types 标志。依赖于 tsconfig.json 设置的 TypeScript 功能,例如路径或者将较新的 JavaScript 语法转换为较旧标准,是故意不支持的。要获得完整的 TypeScript 支持,请参见 完全支持 TypeScript

【The flag --no-experimental-strip-types prevents Node.js from running TypeScript files. By default Node.js will execute only files that contain no TypeScript features that require transformation, such as enums. Node.js will replace inline type annotations with whitespace, and no type checking is performed. To enable the transformation of such features use the flag --experimental-transform-types. TypeScript features that depend on settings within tsconfig.json, such as paths or converting newer JavaScript syntax to older standards, are intentionally unsupported. To get full TypeScript support, see Full TypeScript support.】

类型剥离功能旨在轻量化。通过有意不支持需要生成 JavaScript 代码的语法,并通过用空白替换内联类型,Node.js 可以运行 TypeScript 代码而无需使用源映射。

【The type stripping feature is designed to be lightweight. By intentionally not supporting syntaxes that require JavaScript code generation, and by replacing inline types with whitespace, Node.js can run TypeScript code without the need for source maps.】

类型剥离兼容大多数版本的 TypeScript,但我们建议使用 5.8 或更高版本,并使用以下 tsconfig.json 设置:

【Type stripping is compatible with most versions of TypeScript but we recommend version 5.8 or newer with the following tsconfig.json settings:】

{
  "compilerOptions": {
     "noEmit": true, // Optional - see note below
     "target": "esnext",
     "module": "nodenext",
     "rewriteRelativeImportExtensions": true,
     "erasableSyntaxOnly": true,
     "verbatimModuleSyntax": true
  }
} 

如果你打算只执行 *.ts 文件,例如构建脚本,可以使用 noEmit 选项。如果你打算分发 *.js 文件,则不需要这个标志。

【Use the noEmit option if you intend to only execute *.ts files, for example a build script. You won't need this flag if you intend to distribute *.js files.】

确定模块系统#>

【Determining module system】

Node.js 在 TypeScript 文件中同时支持 CommonJSES 模块 语法。Node.js 不会将一种模块系统转换为另一种;如果你希望代码以 ES 模块运行,必须使用 importexport 语法;如果你希望代码以 CommonJS 运行,则必须使用 requiremodule.exports

【Node.js supports both CommonJS and ES Modules syntax in TypeScript files. Node.js will not convert from one module system to another; if you want your code to run as an ES module, you must use import and export syntax, and if you want your code to run as CommonJS you must use require and 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 扩展名。

【As in JavaScript files, file extensions are mandatory in import statements and import() expressions: import './file.ts', not import './file'. Because of backward compatibility, file extensions are also mandatory in require() calls: require('./file.ts'), not require('./file'), similar to how the .cjs extension is mandatory in require calls in CommonJS files.】

tsconfig.json 选项 allowImportingTsExtensions 将允许 TypeScript 编译器 tsc 检查那些导入时包含 .ts 扩展名的文件的类型。

【The tsconfig.json option allowImportingTsExtensions will allow the TypeScript compiler tsc to type-check files with import specifiers that include the .ts extension.】

TypeScript 功能#>

【TypeScript features】

由于 Node.js 仅移除内联类型,任何涉及用新的 JavaScript 语法替换 TypeScript 语法的 TypeScript 特性都会出错,除非传递了标志 --experimental-transform-types

【Since Node.js is only removing inline types, any TypeScript features that involve replacing TypeScript syntax with new JavaScript syntax will error, unless the flag --experimental-transform-types is passed.】

需要转换的最突出的功能是:

【The most prominent features that require transformation are:】

  • Enum 声明
  • namespace 与运行时代码
  • 带有运行时代码的传统 module
  • 参数属性
  • 导入别名

不包含运行时代码的 namespacesmodule 是被支持的。这个示例将会正确运行:

// This namespace is exporting a type
namespace TypeOnly {
   export type A = string;
} 

这将导致 ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX 错误:

【This will result in ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX error:】

// This namespace is exporting a value
namespace A {
   export let x = 1
} 

由于装饰器目前是一个 TC39 第3阶段提案,并且很快将得到 JavaScript 引擎的支持,所以它们不会被转换,并且会导致解析器错误。这是一个临时限制,未来将会得到解决。

【Since Decorators are currently a TC39 Stage 3 proposal and will soon be supported by the JavaScript engine, they are not transformed and will result in a parser error. This is a temporary limitation and will be resolved in the future.】

此外,Node.js 不会读取 tsconfig.json 文件,也不支持依赖 tsconfig.json 设置的功能,例如路径或将较新的 JavaScript 语法转换为较旧的标准。

【In addition, Node.js does not read tsconfig.json files and does not support features that depend on settings within tsconfig.json, such as paths or converting newer JavaScript syntax into older standards.】

在导入类型时不使用 type 关键字#>

【Importing types without type keyword】

由于类型剥离的特性,type 关键字对于正确剥离类型导入是必要的。没有 type 关键字,Node.js 会将导入视为值导入,这将导致运行时错误。可以使用 tsconfig 选项 verbatimModuleSyntax 来匹配此行为。

【Due to the nature of type stripping, the type keyword is necessary to correctly strip type imports. Without the type keyword, Node.js will treat the import as a value import, which will result in a runtime error. The tsconfig option verbatimModuleSyntax can be used to match this behavior.】

此示例将正常工作:

【This example will work correctly:】

import type { Type1, Type2 } from './module.ts';
import { fn, type FnParams } from './fn.ts'; 

这将导致运行时错误:

【This will result in a runtime error:】

import { Type1, Type2 } from './module.ts';
import { fn, FnParams } from './fn.ts'; 

非文件形式的输入#>

【Non-file forms of input】

--eval 和标准输入 (STDIN) 可以启用类型剥离。模块系统将由 --input-type 决定,就像 JavaScript 一样。

【Type stripping can be enabled for --eval and STDIN. The module system will be determined by --input-type, as it is for JavaScript.】

TypeScript 语法在 REPL、--checkinspect 中不受支持。

【TypeScript syntax is unsupported in the REPL, --check, and inspect.】

源映射#>

【Source maps】

由于内联类型被空格替代,堆栈跟踪中的正确行号不需要源映射;而且 Node.js 不会生成它们。当启用 --experimental-transform-types 时,默认启用源映射。

【Since inline types are replaced by whitespace, source maps are unnecessary for correct line numbers in stack traces; and Node.js does not generate them. When --experimental-transform-types is enabled, source-maps are enabled by default.】

依赖中的类型剥离#>

【Type stripping in dependencies】

为了不鼓励包作者发布用 TypeScript 编写的包,Node.js 不会处理位于 node_modules 路径下的文件夹中的 TypeScript 文件。

【To discourage package authors from publishing packages written in TypeScript, Node.js refuses to handle TypeScript files inside folders under a node_modules path.】

路径别名#>

【Paths aliases】

tsconfig "paths" 不会被转换,因此会产生错误。最接近的可用功能是 子路径导入,但它们的限制是必须以 # 开头。

Node.js 中文网 - 粤ICP备13048890号