@babel/plugin-transform-typescript
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
此插件已包含在 @babel/preset-typescript 中
此插件支持 TypeScript 编程语言 使用的类型语法,但不会添加类型检查能力。如需类型检查功能,您需额外安装并配置 TypeScript。
请注意:虽然 TypeScript 编译器 tsc 支持可选链 (?.)、空值合并 (??) 和类私有字段 (this.#x) 等 JavaScript 提案,但本预设不包含这些特性,因为它们并非 TypeScript 专属的类型语法。如需转译这些特性,建议搭配使用 preset-env 和 preset-typescript。
示例
输入
const x: number = 0;
输出
const x = 0;
安装
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/plugin-transform-typescript
yarn add --dev @babel/plugin-transform-typescript
pnpm add --save-dev @babel/plugin-transform-typescript
bun add --dev @babel/plugin-transform-typescript
用法
通过配置文件(推荐)
{
"plugins": ["@babel/plugin-transform-typescript"]
}
通过命令行
babel --plugins @babel/plugin-transform-typescript script.js
通过 Node API
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-typescript"],
});
配置选项
allowDeclareFields
boolean,默认值 false
添加于 v7.7.0
此功能将在 Babel 8 中默认启用
启用后,仅当类型声明字段带有 declare 修饰符前缀时才会被移除:
class A {
declare foo: string; // Removed
bar: string; // Initialized to undefined
}
allowNamespaces
boolean 类型,默认值为 true。
History
| Version | Changes |
|---|---|
v7.5.0 | Added allowNamespaces, defaults to false |
v7.13.0 | defaults to true |
启用 TypeScript 命名空间的编译支持。
disallowAmbiguousJSXLike
boolean,默认值 false
添加于:v7.16.0
即使未启用 JSX 解析,此选项也会禁止使用可能与 JSX 产生歧义的语法(<X> y 类型断言和 <X>() => {} 类型参数)。其行为与解析 .mts 和 .mjs 文件时的 tsc 保持一致。
dts
boolean,默认值 false
添加于:v7.20.0
此选项将启用 TypeScript 环境上下文(ambient context)中的解析模式,该模式下特定语法遵循不同规则(如 .d.ts 文件及 declare module 块内部)。更多关于环境上下文的信息,请参阅官方手册和《TypeScript Deep Dive》。
isTSX
boolean,默认值 false
强制启用 jsx 解析。否则尖括号将被视为 TypeScript 的旧式类型断言 var foo = <string>bar;。注意:isTSX: true 需配合 allExtensions: true 使用。
jsxPragma
string,默认值 React.createElement
替换编译 JSX 表达式时使用的函数。这有助于识别该导入并非类型导入,不应被移除。
jsxPragmaFrag
string,默认值 React.Fragment
替换编译 JSX 片段表达式时使用的函数。这有助于识别该导入并非类型导入,不应被移除。
onlyRemoveTypeImports
boolean,默认值 false
添加于:v7.9.0
设为 true 时,转换器仅移除纯类型导入(TypeScript 3.8 引入)。仅当使用 TypeScript ≥ 3.8 时启用此选项。
class A {
declare foo: string; // Removed
bar: string; // Initialized to undefined
prop?: string; // Initialized to undefined
prop1!: string // Initialized to undefined
}
optimizeConstEnums
boolean,默认值 false
添加于:v7.15.0
设为 true 时,Babel 将内联枚举值而非使用常规的 enum 输出:
// Input
const enum Animals {
Fish,
}
console.log(Animals.Fish);
// Default output
var Animals;
(function(Animals) {
Animals[(Animals["Fish"] = 0)] = "Fish";
})(Animals || (Animals = {}));
console.log(Animals.Fish);
// `optimizeConstEnums` output
console.log(0);
此选项不同于 TypeScript 的 --isolatedModules 行为(会忽略 const 修饰符并按常规枚举编译),使 Babel 行为与 TypeScript 默认行为保持一致。
但导出 const enum 时,Babel 会将其编译为普通对象字面量,避免依赖跨文件分析:
// Input
export const enum Animals {
Fish,
}
// `optimizeConstEnums` output
export var Animals = {
Fish: 0,
};
TypeScript 编译器选项
官方 TypeScript 编译器提供多种配置选项用于控制编译和类型检查行为。虽然部分选项不适用,但某些行为仍具参考价值,可通过 Babel 的配置选项或插件实现等效功能。
-
--alwaysStrict可通过 parser 选项 的strictMode实现:JavaScriptmodule.exports = {
parserOpts: { strictMode: true },
}; -
--downlevelIteration可使用@babel/plugin-transform-for-of插件。若已使用@babel/preset-env,当编译目标环境不支持for...of时,其将自动通过迭代器转译。 -
--emitDecoratorMetadata此选项为 TypeScript 特有功能,不属装饰器提案标准,官方 Babel 包不提供支持。如需此功能,可使用社区插件 babel-plugin-transform-typescript-metadata。 -
--esModuleInterop这是 Babel 转译 ECMAScript 模块时的默认行为。 -
--experimentalDecorators此选项启用对"传统"装饰器提案的支持。您可以通过@babel/plugin-proposal-decorators插件在 Babel 中启用此功能,但请注意两者存在细微差异。JavaScriptmodule.exports = {
plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
}; -
--importHelpers这相当于@babel/plugin-transform-runtime包的功能。 -
---importsNotUsedAsValues您可以使用onlyRemoveTypeImports选项来模拟此行为。onlyRemoveTypeImports: true相当于importsNotUsedAsValues: preserve,而onlyRemoveTypeImports: false相当于importsNotUsedAsValues: remove。没有与importsNotUsedAsValues: error等效的选项。 -
--inlineSourceMap您可以在babel.config.json文件中设置sourceMaps: "inline"选项。 -
--isolatedModules这是 Babel 的默认行为,且无法关闭,因为 Babel 不支持跨文件分析。 -
--jsxJSX 支持由另一个插件提供。 若希望输出保留 JSX 代码(即--jsx preserve),需使用@babel/plugin-syntax-jsx插件;若需转译为标准 JavaScript(即--jsx react或--jsx react-native),则应使用@babel/plugin-transform-react-jsx插件。 -
--jsxFactory可通过@babel/plugin-transform-react-jsx包的pragma选项进行自定义。同时还需设置本插件的jsxPragma选项。 -
--module,-m若使用打包工具(如 Webpack 或 Rollup),此选项会自动设置。 若使用@babel/preset-env,可通过其modules选项配置;否则需加载特定插件。--module值@babel/preset-env的modules单独插件 Nonefalse/ CommonJS"commonjs"或"cjs"@babel/plugin-transform-modules-commonjsAMD"amd"@babel/plugin-transform-modules-amdSystem"systemjs"@babel/plugin-transform-modules-systemjsUMD"umd"@babel/plugin-transform-modules-umdES6或ES2015false/ -
--outDir使用@babel/cli时,可通过--out-dir选项进行设置。 -
--outFileBabel 不支持合并输出文件,需使用打包工具(如 Webpack、Rollup 或 Parcel)。 使用@babel/cli时,可通过--out-file选项编译单个文件。 -
--sourceMap可使用顶层的sourceMaps: true选项。 -
--targetBabel 不支持指定语言的具体版本,但你可以通过@babel/preset-env选择目标引擎。如果愿意,也可以为每个 ECMAScript 特性单独启用对应插件。 -
--useDefineForClassFields你可以使用setPublicClassFields编译假设来复现此行为。 -
--watch,-w使用@babel/cli时,可通过--watch选项实现监听功能。
注意事项
由于 TypeScript 语言的某些特性依赖于完整的类型系统在运行时进行动态修改,以下注意事项篇幅较长。但值得注意是,其中部分特性仅出现在旧版 TypeScript 代码库中,现代 JavaScript 已提供等效替代方案。
-
Babel 不进行类型检查,因此语法正确但无法通过 TypeScript 类型检查的代码仍可能被转换,且常产生非预期或无效结果。
-
对
tsconfig.json的修改不会影响 Babel。构建过程始终表现为启用了isolatedModules的状态,但许多tsconfig.json选项可通过 Babel 原生方式配置。 -
问:为何 Babel 不允许导出
var或let?答:TypeScript 编译器会根据变量值是否被修改动态改变其使用方式。这本质上依赖于类型模型,超出 Babel 的处理范围。若采用折中方案,需将变量的上下文相关用法统一转换为
Namespace.Value形式(而非直接使用Value),以防止跨文件修改导致的问题。由于相关转换尚未实现,允许导出var或let极可能在使用时产生非预期行为(如同它们不是const)。
命名空间支持限制
若现有代码使用了 TypeScript 特有的命名空间特性,Babel 仅支持其功能子集。编写新代码时建议使用 ES2015 的 import/export 替代命名空间。命名空间特性不会被移除,但存在更现代的替代方案。
-
纯类型声明的
namespace应标记为declare,后续会被安全移除。 -
使用
var或let在namespace中export导出变量将导致错误:"Babel 不支持导出非 const 的命名空间,请改用 const 或..."解决方案:使用
const。如需可变性,请显式使用具有内部可变性的对象。 -
namespaces 不会共享作用域。在 TypeScript 中,引用一个namespace扩展的上下文项时无需显式限定是有效的,编译器会自动添加限定符。但在 Babel 中没有类型模型,无法动态更改引用以匹配父对象的既定类型。参考以下代码:
namespace N {
export const V = 1;
}
namespace N {
export const W = V;
}TypeScript 编译器会将其编译为类似这样:
JavaScriptvar N = {};
(function(N) {
N.V = 1;
})(N);
(function(N) {
N.W = N.V;
})(N);而 Babel 会将其转换为:
JavaScriptvar N;
(function(_N) {
const V = (_N = 1);
})(N || (N = {}));
(function(_N) {
const W = V;
})(N || (N = {}));由于 Babel 不理解
N的类型,对V的引用将变为undefined导致错误。解决方法:显式引用不在同一命名空间定义中的值,即使按照 TypeScript 规则它们应在作用域内。例如:
namespace N {
export const V = 1;
}
namespace N {
export const W = N.V;
}或:
namespace N {
export const V = 1;
export const W = V;
}