@babel/plugin-transform-typescript
此插件包含在 @babel/preset-typescript
中
此插件添加了对 TypeScript 编程语言 使用的类型语法的支持。但是,此插件不会添加类型检查传递给它的 JavaScript 的功能。为此,您需要安装和设置 TypeScript。
请注意,尽管 TypeScript 编译器 tsc
积极支持某些 JavaScript 提案,例如可选链(?.
)、空值合并运算符(??
)和类属性(this.#x
),但此预设不包括这些功能,因为它们不是仅在 TypeScript 中可用的类型语法。如果您想转换这些功能,我们建议将 preset-env
与 preset-typescript
一起使用。
示例
输入
const x: number = 0;
输出
const x = 0;
安装
- npm
- Yarn
- pnpm
npm install --save-dev @babel/plugin-transform-typescript
yarn add --dev @babel/plugin-transform-typescript
pnpm add --save-dev @babel/plugin-transform-typescript
用法
使用配置文件(推荐)
{
"plugins": ["@babel/plugin-transform-typescript"]
}
通过 CLI
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
。
历史
版本 | 更改 |
---|---|
v7.5.0 | 添加了 allowNamespaces ,默认为 false |
v7.13.0 | 默认为 true |
启用 TypeScript 命名空间的编译。
disallowAmbiguousJSXLike
boolean
,默认为 false
添加于:v7.16.0
即使未启用 JSX 解析,此选项也不允许使用与 JSX 不明确的语法(<X> y
类型断言和 <X>() => {}
类型参数)。它与解析 .mts
和 .mjs
文件时 tsc
的行为相匹配。
dts
boolean
,默认为 false
添加于:v7.20.0
此选项将启用在 TypeScript 环境上下文中进行解析,其中某些语法具有不同的规则(例如 .d.ts
文件和 declare module
块内部)。有关环境上下文的更多信息,请参阅 官方手册 和 TypeScript 深入探讨。
isTSX
boolean
,默认为 false
强制启用 jsx
解析。否则,尖括号将被视为 TypeScript 的旧版类型断言 var foo = <string>bar;
。此外,isTSX: true
需要 allExtensions: true
。
jsxPragma
string
,默认为 React
替换编译 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
您可以使用strictMode
解析器选项JavaScriptmodule.exports = {
parserOpts: { strictMode: true },
}; -
--downlevelIteration
您可以使用@babel/plugin-transform-for-of
插件。如果您正在使用@babel/preset-env
,则在您的编译目标不支持for...of
时,它已经使用迭代器进行了转换。 -
--emitDecoratorMetadata
官方 Babel 包不支持此选项,因为它是一个特定于 TypeScript 的添加,而不是装饰器提案的一部分。如果您依赖此功能,则可以使用社区插件 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 不支持跨文件分析。 -
--jsx
JSX 支持是使用另一个插件提供的。如果您希望输出包含 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
单个插件 无
false
/ CommonJS
"commonjs"
或"cjs"
@babel/plugin-transform-modules-commonjs
AMD
"amd"
@babel/plugin-transform-modules-amd
System
"systemjs"
@babel/plugin-transform-modules-systemjs
UMD
"umd"
@babel/plugin-transform-modules-umd
ES6
或ES2015
false
/ -
--outDir
使用@babel/cli
时,可以设置--out-dir
选项。 -
--outFile
Babel 不支持连接输出文件:您应该为此使用捆绑器(如 Webpack、Rollup 或 Parcel)。使用@babel/cli
时,可以使用--out-file
选项 编译单个文件。 -
--sourceMap
您可以使用顶级sourceMaps: true
选项。 -
--target
Babel 不支持定位特定版本的语言,但您可以使用@babel/preset-env
选择要定位的引擎。如果您愿意,可以为每个 ECMAScript 功能启用 单个插件。 -
--useDefineForClassFields
您可以使用setPublicClassFields
假设来复制此行为。 -
--watch
,-w
当使用@babel/cli
时,您可以指定--watch
选项。
注意事项
因为 TypeScript 语言的某些特性依赖于完整的类型系统才能在运行时进行更改。本注意事项部分内容较多,但值得注意的是,其中一些特性只存在于较旧的 TypeScript 代码库中,并且在现代 JavaScript 中已有等效的替代方案,您可能已经在使用这些替代方案。
-
由于 Babel 不进行类型检查,因此语法正确但无法通过 TypeScript 类型检查的代码可能会被成功转换,并且转换结果通常是意外的或无效的。
-
对
tsconfig.json
的更改不会反映在 Babel 中。构建过程的行为始终如同isolatedModules
已启用,但是,Babel 本身提供了一些替代方法来设置许多tsconfig.json
选项。 -
问:为什么 Babel 不允许导出
var
或let
声明的变量?答:TypeScript 编译器会根据值是否被修改来动态更改这些变量的使用方式。最终,这取决于类型模型,超出了 Babel 的范围。一种尽力而为的实现方法是将变量的上下文相关用法转换为始终使用
Namespace.Value
版本而不是Value
,以防它在当前文件之外被修改。因此,允许 Babel 中使用var
或let
(因为转换尚未编写)很可能会在使用时出现错误,就好像它不是const
一样。
部分命名空间支持
如果您现有的代码使用了仅限 TypeScript 的 命名空间 特性。Babel 支持 TypeScript 命名空间特性的一个子集。如果您正在考虑编写使用命名空间的新代码,建议改用 ES2015 的 import
/export
。它 不会消失,但有现代的替代方案。
-
仅类型
namespace
应使用declare
标记,随后将被安全删除。 -
在
namespace
中使用var
或let
export
变量将导致错误:“Babel 不支持导出非 const 变量的命名空间。请改为使用 const 或...”解决方法:使用
const
。如果需要某种形式的修改,请显式使用具有内部可修改性的对象。 -
namespace
不会共享其作用域。在 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;
}