Vai al contenuto principale

@babel/plugin-transform-typescript

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

informazioni

Questo plugin è incluso in @babel/preset-typescript

Questo plugin aggiunge il supporto per la sintassi dei tipi utilizzata dal linguaggio di programmazione TypeScript. Tuttavia, questo plugin non aggiunge la capacità di eseguire il type-checking del JavaScript passato. Per quello, dovrai installare e configurare TypeScript.

Nota che sebbene il compilatore TypeScript tsc supporti attivamente alcune proposte JavaScript come l'optional chaining (?.), il nullish coalescing (??) e le class properties (this.#x), questo preset non include queste funzionalità perché non fanno parte della sintassi dei tipi esclusiva di TypeScript. Raccomandiamo di utilizzare preset-env insieme a preset-typescript se vuoi transpilare queste funzionalità.

Esempio

In

const x: number = 0;

Out

const x = 0;

Installazione

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

Utilizzo

Con un file di configurazione (Consigliato)

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

Tramite CLI

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

Tramite Node API

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

Opzioni

allowDeclareFields

boolean, predefinito false

Aggiunto in v7.7.0

nota

Questa opzione sarà abilitata di default in Babel 8

Quando abilitata, i campi classe di solo tipo vengono rimossi solo se prefissati dal modificatore declare:

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

allowNamespaces

boolean, default: true.

History
VersionChanges
v7.5.0Added allowNamespaces, defaults to false
v7.13.0defaults to true

Abilita la compilazione dei namespace TypeScript.

disallowAmbiguousJSXLike

boolean, predefinito false

Aggiunto in: v7.16.0

Anche quando il parsing JSX non è abilitato, questa opzione vieta l'utilizzo di sintassi ambigua con JSX (asserzioni di tipo <X> y e argomenti di tipo <X>() => {}). Corrisponde al comportamento di tsc durante l'analisi di file .mts e .mjs.

dts

boolean, predefinito false

Aggiunto in: v7.20.0

Questa opzione abilita l'analisi in un contesto ambientale TypeScript, dove alcune sintassi seguono regole diverse (come file .d.ts e all'interno di blocchi declare module). Consulta la Guida Ufficiale e TypeScript Deep Dive per maggiori informazioni sui contesti ambientali.

isTSX

boolean, predefinito false

Abilita forzatamente il parsing jsx. Altrimenti le parentesi angolate verranno interpretate come l'asserzione di tipo legacy di TypeScript var foo = <string>bar;. Inoltre, isTSX: true richiede allExtensions: true.

jsxPragma

string, predefinito React.createElement

Sostituisce la funzione utilizzata durante la compilazione delle espressioni JSX. Questo ci permette di sapere che l'import non è di tipo e non dovrebbe essere rimosso.

jsxPragmaFrag

string, predefinito React.Fragment

Sostituisce la funzione utilizzata durante la compilazione delle espressioni JSX per i frammenti. Questo ci permette di sapere che l'import non è di tipo e non dovrebbe essere rimosso.

onlyRemoveTypeImports

boolean, predefinito false

Aggiunto in: v7.9.0

Quando impostato a true, la trasformazione rimuoverà solo gli type-only imports (introdotti in TypeScript 3.8). Dovrebbe essere utilizzato solo se stai usando 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

boolean, predefinito false

Aggiunto in: v7.15.0

Quando impostato a true, Babel inserirà i valori enum inline invece di utilizzare l'output enum standard:

// 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);

Questa opzione differisce dal comportamento --isolatedModules di TypeScript, che ignora il modificatore const e li compila come normali enum, allineando invece il comportamento di Babel a quello predefinito di TypeScript.

Tuttavia, quando si esporta un const enum Babel lo compilerà come un semplice object literal per non dover dipendere dall'analisi incrociata tra file durante la compilazione:

// Input
export const enum Animals {
Fish,
}

// `optimizeConstEnums` output
export var Animals = {
Fish: 0,
};

Opzioni del Compilatore TypeScript

Il compilatore TypeScript ufficiale offre molte opzioni per configurare come compila ed esegue il type checking. Sebbene molte non siano applicabili, alcuni comportamenti potrebbero essere utili e i loro equivalenti in Babel possono essere abilitati tramite specifiche opzioni di configurazione o plugin.

  • --alwaysStrict Puoi utilizzare l'opzione strictMode del parser:

    JavaScript
    module.exports = {
    parserOpts: { strictMode: true },
    };
  • --downlevelIteration Puoi utilizzare il plugin @babel/plugin-transform-for-of. Se stai usando @babel/preset-env, for...of viene già transpilato utilizzando iteratori quando non è supportato dai tuoi target di compilazione.

  • --emitDecoratorMetadata Questa opzione non è supportata da un pacchetto ufficiale Babel poiché è un'aggiunta specifica di TypeScript e non fa parte della proposta dei decoratori. Se dipendi da questa funzionalità, puoi usare il plugin della community babel-plugin-transform-typescript-metadata.

  • --esModuleInterop Questo è il comportamento predefinito di Babel durante la trasposizione di moduli ECMAScript.

  • --experimentalDecorators Questa opzione abilita il supporto per la proposta di decoratori "legacy". Puoi abilitarla in Babel usando il plugin @babel/plugin-proposal-decorators, ma tieni presente che esistono alcune piccole differenze.

    JavaScript
    module.exports = {
    plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
    };
  • --importHelpers Equivale all'utilizzo del pacchetto @babel/plugin-transform-runtime.

  • ---importsNotUsedAsValues Puoi replicare questo comportamento usando l'opzione onlyRemoveTypeImports. onlyRemoveTypeImports: true equivale a importsNotUsedAsValues: preserve, mentre onlyRemoveTypeImports: false equivale a importsNotUsedAsValues: remove. Non esiste un equivalente per importsNotUsedAsValues: error.

  • --inlineSourceMap Puoi impostare l'opzione sourceMaps: "inline" nel tuo file babel.config.json.

  • --isolatedModules Questo è il comportamento predefinito di Babel e non può essere disabilitato poiché Babel non supporta l'analisi cross-file.

  • --jsx Il supporto JSX è fornito da un altro plugin. Se vuoi che il tuo output contenga codice JSX (es. --jsx preserve), ti serve il plugin @babel/plugin-syntax-jsx; se invece vuoi trasporlo in JavaScript standard (es. --jsx react o --jsx react-native), dovresti usare il plugin @babel/plugin-transform-react-jsx.

  • --jsxFactory Può essere personalizzata usando l'opzione pragma del pacchetto @babel/plugin-transform-react-jsx. È necessario impostare anche l'opzione jsxPragma di questo plugin.

  • --module, -m Se stai usando un bundler (Webpack o Rollup), questa opzione viene impostata automaticamente. Se stai usando @babel/preset-env, puoi usare l'opzione modules; altrimenti puoi caricare il plugin specifico.

    Valore --modulemodules di @babel/preset-envPlugin singolo
    Nonefalse/
    CommonJS"commonjs" o "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 o ES2015false/
  • --outDir Quando usi @babel/cli, puoi impostare l'opzione --out-dir.

  • --outFile Babel non supporta la concatenazione di file di output: per questo dovresti usare un bundler (come Webpack, Rollup o Parcel). Quando usi @babel/cli, puoi compilare un singolo file con l'opzione --out-file.

  • --sourceMap Puoi usare l'opzione globale sourceMaps: true.

  • --target Babel non supporta la specifica di una versione specifica del linguaggio, ma puoi scegliere i motori da supportare usando @babel/preset-env. Se preferisci, puoi abilitare singoli plugin per ogni funzionalità ECMAScript.

  • --useDefineForClassFields Puoi usare l'assunzione setPublicClassFields per replicare questo comportamento.

  • --watch, -w Quando usi @babel/cli, puoi specificare l'opzione --watch.

Avvertenze

Questo perché esistono funzionalità di TypeScript che richiedono l'intero sistema di tipi per apportare modifiche a runtime. Questa sezione di avvertenze è piuttosto lunga, ma vale la pena notare che alcune di queste caratteristiche si trovano solo in codebase TypeScript datate e hanno equivalenti JavaScript moderni che probabilmente usi già.

  1. Poiché Babel non effettua il type-checking, codice sintatticamente corretto ma che fallirebbe il controllo dei tipi TypeScript potrebbe essere trasformato con successo, spesso in modi inaspettati o non validi.

  2. Le modifiche al tuo tsconfig.json non si riflettono in Babel. Il processo di build si comporterà sempre come se isolatedModules fosse attivo, sebbene esistano alternative native Babel per impostare molte opzioni tsconfig.json.

  3. D: Perché Babel non permette l'export di var o let?

    R: Il compilatore TypeScript modifica dinamicamente l'utilizzo di queste variabili in base alla mutazione del valore. Ciò dipende da un modello di tipi ed esula dallo scopo di Babel. Un'implementazione "best-effort" trasformerebbe gli utilizzi contestuali della variabile per usare sempre Namespace.Value invece di Value, nel caso fosse mutata esternamente al file corrente. Consentire var o let in Babel (poiché la trasformazione non è ancora implementata) è quindi più probabile che si manifesti come bug se usate come se non fossero const.

Supporto Parziale ai Namespace

Se disponi di codice esistente che utilizza le funzionalità namespace esclusive di TypeScript, Babel supporta un sottoinsieme di queste. Se stai valutando di scrivere nuovo codice con namespace, si raccomanda invece di usare import/export di ES2015. I namespace non scompariranno, ma esistono alternative moderne.

  • I namespace di solo tipo dovrebbero essere contrassegnati con declare e verranno rimossi in modo sicuro.

  • L'export di una variabile usando var o let in un namespace genererà un errore: "I namespace che esportano non-const non sono supportati da Babel. Cambia in const o..."

    Soluzione alternativa: Usa const. Se è necessaria una forma di mutazione, utilizza esplicitamente un oggetto con mutabilità interna.

  • I namespace non condivideranno il proprio ambito. In TypeScript è valido riferirsi a elementi contestuali estesi da un namespace senza qualificarli, poiché il compilatore aggiunge automaticamente il qualificatore. In Babel non esiste un modello dei tipi ed è impossibile modificare dinamicamente i riferimenti per allinearsi al tipo stabilito dell'oggetto padre.

    Considera questo codice:

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

    Il compilatore TypeScript lo trasforma così:

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

    Mentre Babel lo trasformerà così:

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

    Poiché Babel non comprende il tipo di N, il riferimento a V risulterà undefined generando un errore.

    Soluzione alternativa: Riferirsi esplicitamente ai valori non presenti nella stessa definizione di namespace, anche se sarebbero nell'ambito secondo TypeScript. Esempi:

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

    Oppure:

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