@babel/plugin-transform-typescript
此插件包含在 @babel/preset-typescript
中
¥This plugin is included in @babel/preset-typescript
这个插件增加了对 TypeScript 编程语言 使用的类型语法的支持。但是,这个插件没有添加对传递给它的 JavaScript 进行类型检查的能力。为此,你需要安装和设置 TypeScript。
¥This plugin adds support for the types syntax used by the TypeScript programming language. However, this plugin does not add the ability to type-check the JavaScript passed to it. For that, you will need to install and set up TypeScript.
请注意,尽管 TypeScript 编译器 tsc
积极支持某些 JavaScript 提议,例如可选链 (?.
)、空值合并 (??
) 和类属性 (this.#x
),但此预设不包含这些功能,因为它们不是仅在 TypeScript 中可用的类型语法.如果你想转译这些功能,我们建议使用 preset-env
和 preset-typescript
。
¥Note that although the TypeScript compiler tsc
actively supports certain JavaScript proposals such as optional chaining (?.
), nullish coalescing (??
) and class properties (this.#x
), this preset does not include these features because they are not the types syntax available in TypeScript only. We recommend using preset-env
with preset-typescript
if you want to transpile these features.
示例
¥Example
输入
¥In
const x: number = 0;
输出
¥Out
const x = 0;
安装
¥Installation
- 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
用法
¥Usage
使用配置文件(推荐)
¥With a configuration file (Recommended)
{
"plugins": ["@babel/plugin-transform-typescript"]
}
通过 CLI
¥Via CLI
babel --plugins @babel/plugin-transform-typescript script.js
通过 Node API
¥Via Node API
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-typescript"],
});
选项
¥Options
allowDeclareFields
boolean
,默认为 false
¥boolean
, defaults to false
添加于 v7.7.0
¥Added in v7.7.0
这将在 Babel 8 中默认启用
¥This will be enabled by default in Babel 8
启用后,仅类型的类字段仅在以 declare
修饰符为前缀时才会被删除:
¥When enabled, type-only class fields are only removed if they are prefixed with the declare
modifier:
class A {
declare foo: string; // Removed
bar: string; // Initialized to undefined
}
allowNamespaces
boolean
,默认为 true
。
¥boolean
, defaults to true
.
History
版本 | 变化 |
---|---|
v7.5.0 | 添加了 allowNamespaces ,默认为 false |
v7.13.0 | 默认为 true |
启用 TypeScript 命名空间的编译。
¥Enables compilation of TypeScript namespaces.
disallowAmbiguousJSXLike
boolean
,默认为 false
¥boolean
, defaults to false
添加于:v7.16.0
¥Added in: v7.16.0
即使未启用 JSX 解析,此选项也不允许使用与 JSX 有歧义的语法(<X> y
类型断言和 <X>() => {}
类型参数)。它在解析 .mts
和 .mjs
文件时匹配 tsc
行为。
¥Even when JSX parsing is not enabled, this option disallows using syntax that would be ambiguous with JSX (<X> y
type assertions and <X>() => {}
type arguments). It matches the tsc
behavior when parsing .mts
and .mjs
files.
dts
boolean
,默认为 false
¥boolean
, defaults to false
添加于:v7.20.0
¥Added in: v7.20.0
此选项将在 TypeScript 环境上下文中启用解析,其中某些语法具有不同的规则(例如 .d.ts
文件和 declare module
块内部)。有关环境上下文的更多信息,请参阅 官方手册 和 TypeScript 深潜。
¥This option will enable parsing within a TypeScript ambient context, where certain syntax have different rules (like .d.ts
files and inside declare module
blocks). Please see Official Handbook and TypeScript Deep Dive for more information about ambient contexts.
isTSX
boolean
,默认为 false
¥boolean
, defaults to false
强制启用 jsx
解析。否则尖括号将被视为 TypeScript 的旧版类型断言 var foo = <string>bar;
。此外,isTSX: true
需要 allExtensions: true
。
¥Forcibly enables jsx
parsing. Otherwise angle brackets will be treated as TypeScript's legacy type assertion var foo = <string>bar;
. Also, isTSX: true
requires allExtensions: true
.
jsxPragma
string
,默认为 React.createElement
¥string
, defaults to React.createElement
替换编译 JSX 表达式时使用的函数。这是为了让我们知道导入不是类型导入,不应该被删除。
¥Replace the function used when compiling JSX expressions. This is so that we know that the import is not a type import, and should not be removed.
jsxPragmaFrag
string
,默认为 React.Fragment
¥string
, defaults to React.Fragment
替换编译 JSX 片段表达式时使用的函数。这是为了让我们知道导入不是类型导入,不应该被删除。
¥Replace the function used when compiling JSX fragment expressions. This is so that we know that the import is not a type import, and should not be removed.
onlyRemoveTypeImports
boolean
,默认为 false
¥boolean
, defaults to false
添加于:v7.9.0
¥Added in: v7.9.0
当设置为 true
时,转换只会删除 仅类型导入(在 TypeScript 3.8 中引入)。仅当你使用 TypeScript >= 3.8 时才应使用此选项。
¥When set to true
, the transform will only remove type-only imports (introduced in TypeScript 3.8). This should only be used if you are using 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
¥boolean
, defaults to false
添加于:v7.15.0
¥Added in: v7.15.0
当设置为 true
时,Babel 将内联枚举值而不是使用通常的 enum
输出:
¥When set to true
, Babel will inline enum values rather than using the usual enum
output:
// 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 的默认行为对齐。
¥This option differs from TypeScript's --isolatedModules
behavior, which ignores the const
modifier and compiles them as normal enums, and aligns Babel's behavior with TypeScript's default behavior.
但是,当导出 const enum
Babel 时,会将其编译为纯对象字面量,以便在编译时不需要依赖跨文件分析:
¥However, when exporting a const enum
Babel will compile it to a plain object literal so that it doesn't need to rely on cross-file analysis when compiling it:
// Input
export const enum Animals {
Fish,
}
// `optimizeConstEnums` output
export var Animals = {
Fish: 0,
};
TypeScript 编译器选项
¥TypeScript Compiler Options
官方的 TypeScript 编译器有许多 选项 用于配置它的编译方式和类型检查。虽然许多不适用,但某些行为可能有用,并且它们在 Babel 中的等价物可以通过一些配置选项或插件来启用。
¥The official TypeScript compiler has many options for configuring how it compiles and type checks. While many don't apply, some behaviors might be useful and their equivalents in Babel can be enabled by some configuration options or plugins.
-
--alwaysStrict
你可以使用strictMode
解析器选项:¥
--alwaysStrict
You can use thestrictMode
parser option:JavaScriptmodule.exports = {
parserOpts: { strictMode: true },
}; -
--downlevelIteration
你可以使用@babel/plugin-transform-for-of
插件。如果你使用的是@babel/preset-env
,当你的编译目标不支持for...of
时,它已经使用迭代器进行了转译。¥
--downlevelIteration
You can use the@babel/plugin-transform-for-of
plugin. If you are using@babel/preset-env
,for...of
is already transpiled using iterators when it isn't supported by your compilation target(s). -
--emitDecoratorMetadata
官方 Babel 包不支持此选项,因为它是特定于 TypeScript 的附加项,而不是装饰器提案的一部分。如果你依赖这个特性,你可以使用社区插件 babel-plugin-transform-typescript-metadata。¥
--emitDecoratorMetadata
This option isn't supported by an official Babel package since it is a TypeScript-specific addition and not part of the decorators proposal. If you rely on this feature, you can use the community plugin babel-plugin-transform-typescript-metadata. -
--esModuleInterop
这是 Babel 在转译 ECMAScript 模块时的默认行为。¥
--esModuleInterop
This is the default behavior of Babel when transpiling ECMAScript modules. -
--experimentalDecorators
此选项启用对 "legacy" 装饰器提案的支持。你可以使用@babel/plugin-proposal-decorators
插件在 Babel 中启用它,但请注意,存在一些细微差别。¥
--experimentalDecorators
This option enables support for the "legacy" decorator proposal. You can enable it in Babel using the@babel/plugin-proposal-decorators
plugin, but please be aware, there are some minor differences.JavaScriptmodule.exports = {
plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
}; -
--importHelpers
这相当于@babel/plugin-transform-runtime
包。¥
--importHelpers
This is the equivalent of the@babel/plugin-transform-runtime
package. -
---importsNotUsedAsValues
你可以使用onlyRemoveTypeImports
选项来复制此行为。onlyRemoveTypeImports: true
等价于importsNotUsedAsValues: preserve
,而onlyRemoveTypeImports: false
等价于importsNotUsedAsValues: remove
。importsNotUsedAsValues: error
没有等价物。¥
---importsNotUsedAsValues
You can use theonlyRemoveTypeImports
option to replicate this behavior.onlyRemoveTypeImports: true
is equivalent toimportsNotUsedAsValues: preserve
, whileonlyRemoveTypeImports: false
is equivalent toimportsNotUsedAsValues: remove
. There is no equivalent forimportsNotUsedAsValues: error
. -
--inlineSourceMap
你可以在babel.config.json
文件中设置sourceMaps: "inline"
选项。¥
--inlineSourceMap
You can set thesourceMaps: "inline"
option in yourbabel.config.json
file. -
--isolatedModules
这是 Babel 的默认行为,无法关闭,因为 Babel 不支持跨文件分析。¥
--isolatedModules
This is the default Babel behavior, and it can't be turned off because Babel doesn't support cross-file analysis. -
--jsx
JSX 支持是使用另一个插件提供的。如果你想让你的输出包含 JSX 代码(即--jsx preserve
),你需要@babel/plugin-syntax-jsx
插件;如果你想将它转换为标准的 JavaScript(即--jsx react
或--jsx react-native
),你应该使用@babel/plugin-transform-react-jsx
插件。¥
--jsx
JSX support is provided using another plugin. If you want your output to contains JSX code (i.e.--jsx preserve
), you need the@babel/plugin-syntax-jsx
plugin; if you want to transpile it to standard JavaScript (i.e.--jsx react
or--jsx react-native
), you should use the@babel/plugin-transform-react-jsx
plugin. -
--jsxFactory
它可以使用@babel/plugin-transform-react-jsx
包的pragma
选项 进行定制。你还需要设置此插件的jsxPragma
选项。¥
--jsxFactory
It can be customized using thepragma
option of the@babel/plugin-transform-react-jsx
package. You also need to set thejsxPragma
option of this plugin. -
--module
,-m
如果你使用打包器(Webpack 或 Rollup),此选项会自动设置。如果你使用的是@babel/preset-env
,则可以使用modules
选项;否则你可以加载特定的插件。¥
--module
,-m
If you are using a bundler (Webpack or Rollup), this option is set automatically. If you are using@babel/preset-env
, you can use themodules
option; otherwise you can load the specific plugin.--module
值@babel/preset-env
的modules
单个插件 None
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
选项。¥
--outDir
When using@babel/cli
, you can set the--out-dir
option. -
--outFile
Babel 不支持连接输出文件:你应该为此使用打包器(如 Webpack、Rollup 或 Parcel)。使用@babel/cli
时,可以使用--out-file
选项 编译单个文件。¥
--outFile
Babel doesn't support concatenating output files: you should use a bundler (like Webpack, Rollup or Parcel) for that. When using@babel/cli
, you can compile a single file using the--out-file
option. -
--sourceMap
你可以使用顶层sourceMaps: true
选项。¥
--sourceMap
You can use the top-levelsourceMaps: true
option. -
--target
Babel 不支持针对语言的特定版本,但你可以使用@babel/preset-env
选择要针对的引擎。如果你愿意,可以为每个 ECMAScript 功能启用 个人插件。¥
--target
Babel doesn't support targeting a specific version of the language, but you can choose which engines you want to target using@babel/preset-env
. If you prefer, you can enable individual plugins for every ECMAScript feature. -
--useDefineForClassFields
你可以使用setPublicClassFields
假设来复制此行为。¥
--useDefineForClassFields
You can use thesetPublicClassFields
assumption to replicate this behavior. -
--watch
、-w
使用@babel/cli
时,可以指定--watch
选项。¥
--watch
,-w
When using@babel/cli
, you can specify the--watch
option.
注意事项
¥Caveats
因为 TypeScript 语言的一些特性依赖于完整的类型系统,可以在运行时进行更改。这部分注意事项很长,但是值得注意的是,其中一些功能仅在较旧的 TypeScript 代码库中找到,并且具有你可能已经在使用的现代 JavaScript 等效项。
¥Because there are features of the TypeScript language which rely on the full type-system to be available to make changes at runtime. This section of caveats is quite long, however, it's worth noting that a few of these features are only found in older TypeScript codebases and have modern JavaScript equivalents which you are probably already using.
-
由于 Babel 不进行类型检查,因此语法正确但无法通过 TypeScript 类型检查的代码可能会成功转换,并且通常以意想不到或无效的方式进行转换。
¥Since Babel does not type-check, code which is syntactically correct, but would fail the TypeScript type-checking may successfully get transformed, and often in unexpected or invalid ways.
-
对你的
tsconfig.json
所做的更改不会反映在 babel 中。构建过程将始终表现得好像isolatedModules
已打开,但是有 Babel-native 替代方法来设置很多tsconfig.json
options。¥Changes to your
tsconfig.json
are not reflected in babel. The build process will always behave as thoughisolatedModules
is turned on, there are Babel-native alternative ways to set a lot of thetsconfig.json
options however. -
问:为什么 Babel 不允许导出
var
或let
?¥Q: Why doesn't Babel allow export of a
var
orlet
?答:TypeScript 编译器会根据值是否发生变化动态更改这些变量的使用方式。最终,这取决于类型模型,并且超出了 Babel 的范围。一个尽力而为的实现会将变量的上下文相关用法转换为始终使用
Namespace.Value
版本而不是Value
,以防它在当前文件之外发生修改。因此,允许来自 Babel 的var
或let
(因为尚未编写转换)在使用时更有可能将其自身展示为错误,就好像它不是const
一样。¥A: The TypeScript compiler dynamically changes how these variables are used depending on whether or not the value is mutated. Ultimately, this depends on a type-model and is outside the scope of Babel. A best-effort implementation would transform context-dependent usages of the variable to always use the
Namespace.Value
version instead ofValue
, in case it was mutated outside of the current file. Allowingvar
orlet
from Babel (as the transform is not-yet-written) is therefore is more likely than not to present itself as a bug when used as-if it was notconst
.
公正的命名空间支持
¥Impartial Namespace Support
如果你有现有代码使用 TypeScript-only namespace 功能。Babel 支持 TypeScript 命名空间功能的一个子集。如果你正在考虑编写使用命名空间的新代码,建议使用 ES2015 import
/export
。它是 不会离开,但有现代替代品。
¥If you have existing code which uses the TypeScript-only namespace features. Babel supports a subset of TypeScript's namespace features. If you are considering writing new code which uses namespace, using the ES2015 import
/export
is recommended instead. It's not going away, but there are modern alternatives.
-
仅限类型的
namespace
应标记为declare
,随后将被安全删除。¥Type-only
namespace
s should be marked withdeclare
and will subsequently be safely removed. -
在
namespace
中使用var
或let
对变量进行export
操作会导致错误:“Babel 不支持导出非常量的命名空间。更改为 const 或...”¥
export
ing a variable usingvar
orlet
in anamespace
will result in an error: "Namespaces exporting non-const are not supported by Babel. Change to const or ..."解决方法:使用
const
。如果需要某种形式的突变,请显式使用具有内部可变性的对象。¥Workaround: Use
const
. If some form of mutation is required, explicitly use an object with internal mutability. -
namespace
不会分享他们的范围。在 TypeScript 中,引用namespace
扩展的上下文项而不限定它们是有效的,编译器将添加限定符。在 Babel 中,没有 type-model,不可能动态改变引用来匹配父对象的既定类型。¥
namespace
s will not share their scope. In TypeScript, it is valid to refer to contextual items that anamespace
extends without qualifying them, and the compiler will add the qualifier. In Babel, there is no type-model, and it is impossible to dynamically change references to match the established type of the parent object.考虑这段代码:
¥Consider this code:
namespace N {
export const V = 1;
}
namespace N {
export const W = V;
}TypeScript 编译器将其编译为如下内容:
¥The TypeScript compiler compiles it to something like this:
JavaScriptvar N = {};
(function(N) {
N.V = 1;
})(N);
(function(N) {
N.W = N.V;
})(N);而 Babel 会将它转换成这样的东西:
¥While Babel will transform it to something like this:
JavaScriptvar N;
(function(_N) {
const V = (_N = 1);
})(N || (N = {}));
(function(_N) {
const W = V;
})(N || (N = {}));由于 Babel 不理解
N
的类型,所以对V
的引用将是undefined
导致错误。¥As Babel doesn't understand the type of
N
, the reference toV
will beundefined
resulting in an error.解决方法:显式引用不在同一命名空间定义中的值,即使它们在 TypeScript 的范围内。示例:
¥Workaround: Explicitly refer to values not in the same namespace definition, even if they would be in the scope according to TypeScript. Examples:
namespace N {
export const V = 1;
}
namespace N {
export const W = N.V;
}或者:
¥Or:
namespace N {
export const V = 1;
export const W = V;
}