Node.js v22.8.0 文档


模块:TypeScript#

¥Modules: TypeScript

稳定性: 1.0 - 早期开发

¥Stability: 1.0 - Early development

启用#

¥Enabling

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

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

  1. 对于 TypeScript 的所有语法和功能的 完全支持,包括使用任何版本的 TypeScript,请使用第三方包。

    ¥For full support of all of TypeScript's syntax and features, including using any version of TypeScript, use a third-party package.

  2. 对于轻量级支持,你可以使用对 类型剥离 的内置支持。

    ¥For lightweight support, you can use the built-in support for type stripping.

完全支持 TypeScript#

¥Full TypeScript support

要使用完全支持所有 TypeScript 功能(包括 tsconfig.json)的 TypeScript,你可以使用第三方包。这些说明使用 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

    ¥Install the package as a development dependency using whatever package manager you're using for your project. For example, with npm:

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

    ¥Then you can run your TypeScript code via:

    npx tsx your-file.ts 

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

    ¥Or alternatively, you can run with node via:

    node --import=tsx your-file.ts 

类型剥离#

¥Type stripping

稳定性: 1.0 - 早期开发

¥Stability: 1.0 - Early development

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

¥The flag --experimental-strip-types enables Node.js to run TypeScript files. By default Node.js will execute only files that contain no TypeScript features that require transformation, such as enums or namespaces. 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.

确定模块系统#

¥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 文件相同。 要使用 importexport 语法,请将 "type": "module" 添加到最近的父级 package.json

    ¥.ts files will have their module system determined the same way as .js files. To use import and export syntax, add "type": "module" to the nearest parent package.json.

  • .mts 文件将始终作为 ES 模块运行,类似于 .mjs 文件。

    ¥.mts files will always be run as ES modules, similar to .mjs files.

  • .cts 文件将始终作为 CommonJS 模块运行,类似于 .cjs 文件。

    ¥.cts files will always be run as CommonJS modules, similar to .cjs files.

  • .tsx 文件不受支持。

    ¥.tsx files are unsupported.

与 JavaScript 文件一样,import 语句和 import() 表达式中的 文件扩展名是强制性的import './file.ts',不是 import './file'。由于向后兼容,文件扩展名在 require() 调用中也是强制性的:require('./file.ts'),而不是 require('./file'),类似于 .cjs 扩展在 CommonJS 文件中的 require 调用中是必需的。

¥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 扩展名的 import 说明符对文件进行类型检查。

¥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

  • namespaces

  • legacy module

  • 参数属性

    ¥parameter properties

由于装饰器当前是 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 启用类型剥离。模块系统将由 --input-type 确定,就像 JavaScript 一样。

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

REPL、STDIN 输入、--print--checkinspect 不支持 TypeScript 语法。

¥TypeScript syntax is unsupported in the REPL, STDIN input, --print, --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 will by default refuse to handle TypeScript files inside folders under a node_modules path.