跳至主要內容

@babel/plugin-transform-typescript

資訊

此外掛程式包含在 @babel/preset-typescript

此外掛程式新增支援 TypeScript 程式語言 所使用的類型語法。不過,此外掛程式並未新增檢查傳遞給它的 JavaScript 的類型功能。若要執行此功能,您需要安裝並設定 TypeScript。

請注意,儘管 TypeScript 編譯器 tsc 積極支援某些 JavaScript 提案,例如可選鏈接 (?.)、空值合併 (??) 和類別屬性 (this.#x),但這個預設值不包含這些功能,因為它們不是僅在 TypeScript 中可用的類型語法。如果您想轉譯這些功能,我們建議將 preset-envpreset-typescript 搭配使用。

範例

輸入

const x: number = 0;

輸出

const x = 0;

安裝

npm install --save-dev @babel/plugin-transform-typescript

用法

babel.config.json
{
"plugins": ["@babel/plugin-transform-typescript"]
}

透過 CLI

Shell
babel --plugins @babel/plugin-transform-typescript script.js

透過 Node API

JavaScript
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-typescript"],
});

選項

allowDeclareFields

布林值,預設為 false

新增於 v7.7.0

注意

這將在 Babel 8 中預設啟用

啟用時,只有加上 declare 修飾詞前綴的類型專用類別欄位才會被移除

JavaScript
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

布林值,預設為 false

新增於:v7.16.0

即使未啟用 JSX 解析,此選項仍禁止使用與 JSX 相似的語法(<X> y 類型斷言和 <X>() => {} 類型參數)。它與解析 .mts.mjs 檔案時的 tsc 行為相符。

dts

布林值,預設為 false

新增於:v7.20.0

此選項將啟用在 TypeScript 環境背景下的解析,其中某些語法有不同的規則(例如 .d.ts 檔案和 declare module 區塊內)。請參閱 官方手冊TypeScript 深入探討 以取得有關環境背景的更多資訊。

isTSX

布林值,預設為 false

強制啟用 jsx 解析。否則,尖括號將被視為 TypeScript 的舊式類型斷言 var foo = <string>bar;。此外,isTSX: true 需要 allExtensions: true

jsxPragma

string,預設為 React

取代編譯 JSX 表達式時使用的函式。這樣我們就知道匯入不是類型匯入,不應移除。

jsxPragmaFrag

字串,預設為 React.Fragment

取代編譯 JSX 片段運算式時使用的函式。這樣我們就知道匯入不是類型匯入,不應移除。

onlyRemoveTypeImports

布林值,預設為 false

新增於:v7.9.0

設為 true 時,轉換只會移除 僅類型匯入(在 TypeScript 3.8 中引入)。這只能在使用 TypeScript >= 3.8 時使用。

JavaScript
class A {
declare foo: string; // Removed
bar: string; // Initialized to undefined
prop?: string; // Initialized to undefined
prop1!: string // Initialized to undefined
}

optimizeConstEnums

布林值,預設為 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 解析器選項

    JavaScript
    module.exports = {
    parserOpts: { strictMode: true },
    };
  • --downlevelIteration 您可以使用 @babel/plugin-transform-for-of 外掛程式。如果您使用 @babel/preset-envfor...of 已經使用迭代器轉譯,而您的編譯目標不支援時。

  • --emitDecoratorMetadata 此選項不受官方 Babel 套件支援,因為它是 TypeScript 特定的新增功能,不屬於裝飾器提案的一部分。如果您依賴此功能,可以使用社群外掛程式 babel-plugin-transform-typescript-metadata

  • --esModuleInterop 這是 Babel 在轉譯 ECMAScript 模組時的預設行為。

  • --experimentalDecorators 此選項啟用對「舊版」裝飾器提案的支援。您可以在 Babel 中使用 @babel/plugin-proposal-decorators 外掛程式啟用它,但請注意,有一些細微的差異。

    JavaScript
    module.exports = {
    plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
    };
  • --importHelpers 這等於 @babel/plugin-transform-runtime 套件。

  • ---importsNotUsedAsValues 您可以使用 onlyRemoveTypeImports 選項來複製此行為。onlyRemoveTypeImports: true 等於 importsNotUsedAsValues: preserve,而 onlyRemoveTypeImports: false 等於 importsNotUsedAsValues: removeimportsNotUsedAsValues: error 沒有等效選項。

  • --inlineSourceMap 您可以設定 sourceMaps: "inline" 選項在您的 babel.config.json 檔案中。

  • --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-envmodules單一外掛
    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
    ES6ES2015false/
  • --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 等價物。

  1. 由於 Babel 沒有進行類型檢查,語法正確但無法通過 TypeScript 類型檢查的程式碼可能會成功轉換,而且通常會以意外或無效的方式轉換。

  2. tsconfig.json 的變更不會反映在 babel 中。建置程序的行為永遠會像是 isolatedModules 已開啟,不過有許多 tsconfig.json 選項 有 Babel 原生的替代方式可以設定。

  3. :為什麼 Babel 不允許匯出 varlet

    :TypeScript 編譯器會動態變更這些變數的使用方式,具體取決於值是否已變異。最終,這取決於類型模型,且超出 Babel 的範圍。盡力而為的實作會將變數的依據脈絡使用方式轉換為始終使用 Namespace.Value 版本,而非 Value,以防在目前檔案外變異。因此,允許從 Babel 匯出 varlet(由於轉換尚未撰寫)在用作非 const 時,很可能會表現為錯誤。

公正的命名空間支援

如果您有現有的程式碼使用僅限 TypeScript 的 命名空間 功能。Babel 支援 TypeScript 命名空間功能的子集。如果您正在考慮撰寫使用命名空間的新程式碼,建議改用 ES2015 import/export。它 不會消失,但有現代的替代方案。

  • 僅限類型的 namespace 應標記為 declare,之後會安全移除。

  • namespace 中使用 varlet export 變數會導致錯誤:「Babel 不支援匯出非常數的命名空間。變更為 const 或 ...」

    解決方法:使用 const。如果需要某種形式的變異,請明確使用具有內部可變性的物件。

  • namespace 彼此不會共用範圍。在 TypeScript 中,可以參照 namespace 延伸的內容項目,而不用限定它們,且編譯器會加入限定詞。Babel 沒有類型模型,無法動態變更參照,以符合父物件的既定類型。

    請考慮下列程式碼

    namespace N {
    export const V = 1;
    }
    namespace N {
    export const W = V;
    }

    TypeScript 編譯器會將其編譯成類似以下的程式碼

    JavaScript
    var N = {};
    (function(N) {
    N.V = 1;
    })(N);
    (function(N) {
    N.W = N.V;
    })(N);

    而 Babel 會將其轉換成類似以下的程式碼

    JavaScript
    var N;
    (function(_N) {
    const V = (_N = 1);
    })(N || (N = {}));
    (function(_N) {
    const W = V;
    })(N || (N = {}));

    由於 Babel 不了解 N 的類型,因此對 V 的參照會是 undefined,導致錯誤。

    解決方法:明確參照不在同一個 namespace 定義中的值,即使它們根據 TypeScript 會在範圍內。範例

    namespace N {
    export const V = 1;
    }
    namespace N {
    export const W = N.V;
    }

    namespace N {
    export const V = 1;
    export const W = V;
    }