Node.js原生支持TypeScript?开发者需要了解的一切

前有科技后进阶 2025-04-24 08:55:55

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!

随着 Node.js v23.6.0 的发布,开发者现在可以在 Node.js 中原生使用 TypeScript,无需额外的转译工具(例如: ts-node)或新增手动编译步骤。该功能显著简化了开发和构建流程,并通过降低复杂性提升了整体开发体验。

1. 新功能速览

以下是一个简单的 TypeScript 示例,演示了 Node.js 对 TypeScript 的原生支持:

// demo.mtsfunction main(message: string): void { console.log('Message:' + message);}main('Hello!');

而以前,在 Node.js 中运行 TypeScript 需要使用 TypeScript 编译器 (tsc) 或 ts-node 之类的工具进行转译。而从 Node v23.6.0 开始,开发者可以直接运行该文件:

node demo.mts// 注意:需要 Node.js v23.6.0 以上版本

而且,运行此命令将产生以下警告:

ExperimentalWarning: Type Stripping is an experimental feature and might change at any time

由于类型剥离 (Type Stripping) 仍处于实验阶段,因此尚不建议在生产环境使用且未来可能随时变更。如果要在开发设置中隐藏警告,可以通过下面的命令:

node --disable-warning=ExperimentalWarning demo.mts// 临时取消警告export NODE_OPTIONS="--disable-warning=ExperimentalWarning"// 永久取消警告

对于长期配置,开发者可以将其存储在 .bashrc、.zshrc 或 .env 文件中,或在 IDE 设置中对其进行配置。

2. 在 Node.js 实际项目中使用 TypeScript

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

全面支持 TypeScript 的所有语法和功能,包括:使用任意版本的 TypeScript,可以使用第三方软件包为了获得轻量级支持,开发者可以使用内置的类型剥离支持2.1 全面支持 TypeScript

要在 Node.js 中使用 TypeScript 并完全支持所有 TypeScript 功能,包括: tsconfig.json,开发者可以使用第三方软件包。下面以 tsx 为例,但还有许多其他类似的库可用。

npm install --save-dev tsx

然后可以通过以下方式运行 TypeScript 代码:

npx tsx your-file.ts// 或者使用 node 命名运行node --import=tsx your-file.ts2.2 使用类型剥离 (Type Stripping) 方式

默认情况下,Node.js 会执行仅包含可擦除 TypeScript 语法 (Erasable TypeScript Syntax) 的 TypeScript 文件。

Node.js 会将 TypeScript 语法替换为空格,并且不执行类型检查 。要启用不可擦除 TypeScript 语法的转换,例如:Enum、namespace、参数属性、导入别名、module 等,开发者可以使用 --experimental-transform-types 标志,而要禁用此功能,可以使用 --no-experimental-strip-types 标志。

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

同时,Node.js 会忽略 tsconfig.json 文件,因此依赖于 tsconfig.json 中设置的功能,例如:路径或将较新的 JavaScript 语法转换为较旧的标准将不受支持。

类型剥离旨在保证轻量级且有意不支持需要转化为 JavaScript 的语法,并将内联类型替换为空格,无需 Source Map 即可运行 TypeScript 代码。

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

{ "compilerOptions": { "noEmit": true, // 如果只想执行 *.ts 文件可使用 noEmit 选项 // 如果打算分发 *.js 文件,则无需使用此标志 "target": "esnext", "module": "nodenext", "rewriteRelativeImportExtensions": true, "erasableSyntaxOnly": true, "verbatimModuleSyntax": true }}

一个常见的场景是在 TypeScript 中导入流行的 Node.js 库,例如:

import {writeFileSync} from 'fs';function saveMessage(message: string): void { writeFileSync('message.txt', message);}saveMessage('Hello, Node.js!');

上面示例表明原生 TypeScript 可以与标准 Node.js 模块无缝协作。需要注意的是,Node.js 通过扩展名区分文件类型:

.ts:ESM 或 CommonJS,取决于 package.json 的 “type” 字段.mts:始终视为 ESM.cts:始终视为 CommonJS.tsx:目前不支持

开发者必须谨慎选择文件名,以保持与 Node.js 模块的兼容性。

3.Node.js TypeScript 与传统 TypeScript 的不同

Node.js 通过类型剥离(无需转译即可移除类型注释)实现了原生 TypeScript 支持。主要限制和解决方法包括:

3.1 不支持的 TypeScript 特定功能及替代方案

3.2 本地导入需要 .ts 扩展名// 传统方式import {myFunction} from './my-module.js';// Node.js 原生 TS 支持import {myFunction} from './my-module.ts';3.3 需要显式导入类型import type {Cat, Dog} from './animal.ts';3.4 --input-type CLI 选项

从标准输入 stdin 或使用 --eval 运行 TypeScript 代码时,开发者需要使用 --input-type 明确指定解释:

echo 'console.log("Hello"as const)' | node --input-type module-typescript3.5 类型剥离(Type stripping)和 Source Map

类型剥离可保留空格以实现精确调试,并消除 Source Map 依赖性:

function describeColor(color: Color): string { return `Color named "${color.colorName}"`;}type Color = {colorName: string};describeColor({colorName: 'green'});Post-type-stripping JavaScript:function describeColor(color) { return `Color named "${color.colorName}"`;}describeColor({colorName: 'green'});4. 结论

Node.js v23.6.0 版本新增了原生 TypeScript 支持,无疑是一个重大进步,其简化了 TypeScript 工作流程,并减少了对打包工具的依赖。虽然仍然存在一些限制,但未来的增强功能(--experimental-transform-types)可能会进一步扩展 Node.js 的 TypeScript 功能。

参考资料

https://nodejs.org/api/typescript.html

https://nodesource.com/blog/Node.js-Supports-TypeScript-Natively

https://dev.to/kevin-uehara/node-will-finally-suport-typescript-18k6

0 阅读:0

前有科技后进阶

简介:感谢大家的关注