Aller au contenu principal

@babel/plugin-transform-typescript

Traduction Bêta Non Officielle

Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →

info

Ce plugin est inclus dans @babel/preset-typescript

Ce plugin ajoute la prise en charge de la syntaxe de typage utilisée par le langage de programmation TypeScript. Cependant, ce plugin n'ajoute pas la capacité de vérifier les types du JavaScript qui lui est transmis. Pour cela, vous devrez installer et configurer TypeScript.

Notez que bien que le compilateur TypeScript tsc prenne activement en charge certaines propositions JavaScript comme le chaînage optionnel (?.), la coalescence des nuls (??) et les propriétés de classe (this.#x), ce préréglage n'inclut pas ces fonctionnalités car elles ne sont pas spécifiques à la syntaxe de typage de TypeScript. Nous recommandons d'utiliser preset-env avec preset-typescript si vous souhaitez transpiler ces fonctionnalités.

Exemple

Entrée

const x: number = 0;

Sortie

const x = 0;

Installation

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

Utilisation

Avec un fichier de configuration (Recommandé)

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

Via CLI

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

Via l'API Node

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

Options

allowDeclareFields

boolean, valeur par défaut : false

Ajouté dans v7.7.0

note

Activé par défaut dans Babel 8

Lorsqu'activé, les champs de classe purement typés ne sont supprimés que s'ils sont préfixés par le modificateur declare :

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

allowNamespaces

boolean, par défaut true.

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

Active la compilation des namespaces TypeScript.

disallowAmbiguousJSXLike

boolean, valeur par défaut : false

Ajouté dans la version : v7.16.0

Même lorsque l'analyse JSX n'est pas activée, cette option interdit d'utiliser une syntaxe ambiguë avec JSX (assertions de type <X> y et arguments de type <X>() => {}). Elle correspond au comportement de tsc lors de l'analyse des fichiers .mts et .mjs.

dts

boolean, valeur par défaut : false

Ajouté dans la version : v7.20.0

Cette option activera l'analyse dans un contexte ambiant TypeScript, où certaines syntaxes suivent des règles différentes (comme les fichiers .d.ts et dans les blocs declare module). Consultez le Guide Officiel et TypeScript Deep Dive pour plus d'informations sur les contextes ambiants.

isTSX

boolean, valeur par défaut : false

Force l'activation de l'analyse jsx. Sinon, les chevrons seront traités comme l'ancienne assertion de type TypeScript var foo = <string>bar;. De plus, isTSX: true nécessite allExtensions: true.

jsxPragma

string, valeur par défaut : React.createElement

Remplace la fonction utilisée lors de la compilation des expressions JSX. Cela permet d'identifier que l'import n'est pas un import de type et ne doit pas être supprimé.

jsxPragmaFrag

string, valeur par défaut : React.Fragment

Remplace la fonction utilisée lors de la compilation des expressions de fragments JSX. Cela permet d'identifier que l'import n'est pas un import de type et ne doit pas être supprimé.

onlyRemoveTypeImports

boolean, valeur par défaut : false

Ajouté dans : v7.9.0

Lorsque défini sur true, la transformation ne supprimera que les imports de type uniquement (introduits dans TypeScript 3.8). Ne doit être utilisé que si vous utilisez 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, valeur par défaut : false

Ajouté dans : v7.15.0

Lorsque défini sur true, Babel inline les valeurs d'énumération plutôt que d'utiliser le résultat enum habituel :

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

Cette option diffère du comportement --isolatedModules de TypeScript, qui ignore le modificateur const et les compile comme des enums normaux, et aligne le comportement de Babel sur celui par défaut de TypeScript.

Cependant, lors de l'exportation d'un const enum, Babel le compilera en un simple objet littéral pour éviter de dépendre d'une analyse multi-fichiers :

// Input
export const enum Animals {
Fish,
}

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

Options du compilateur TypeScript

Le compilateur TypeScript officiel propose de nombreuses options pour configurer sa compilation et sa vérification de types. Bien que beaucoup ne s'appliquent pas, certains comportements peuvent être utiles et leurs équivalents dans Babel peuvent être activés via des options de configuration ou des plugins.

  • --alwaysStrict Vous pouvez utiliser l'option de parseur strictMode :

    JavaScript
    module.exports = {
    parserOpts: { strictMode: true },
    };
  • --downlevelIteration Vous pouvez utiliser le plugin @babel/plugin-transform-for-of. Si vous utilisez @babel/preset-env, for...of est déjà transpilé en utilisant des itérateurs lorsque non supporté par votre(es) cible(s) de compilation.

  • --emitDecoratorMetadata Cette option n'est pas supportée par un package officiel Babel car c'est un ajout spécifique à TypeScript qui ne fait pas partie de la proposition des décorateurs. Si vous dépendez de cette fonctionnalité, vous pouvez utiliser le plugin communautaire babel-plugin-transform-typescript-metadata.

  • --esModuleInterop Ce comportement est activé par défaut dans Babel lors de la transpilation de modules ECMAScript.

  • --experimentalDecorators Cette option active le support de la proposition de décorateurs "legacy". Vous pouvez l'activer dans Babel en utilisant le plugin @babel/plugin-proposal-decorators, mais notez qu'il existe quelques différences mineures.

    JavaScript
    module.exports = {
    plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
    };
  • --importHelpers L'équivalent est le package @babel/plugin-transform-runtime.

  • ---importsNotUsedAsValues Vous pouvez utiliser l'option onlyRemoveTypeImports pour reproduire ce comportement. onlyRemoveTypeImports: true équivaut à importsNotUsedAsValues: preserve, tandis que onlyRemoveTypeImports: false équivaut à importsNotUsedAsValues: remove. Il n'existe pas d'équivalent pour importsNotUsedAsValues: error.

  • --inlineSourceMap Vous pouvez configurer l'option sourceMaps: "inline" dans votre fichier babel.config.json.

  • --isolatedModules Ce comportement est activé par défaut dans Babel et ne peut pas être désactivé car Babel ne prend pas en charge l'analyse inter-fichiers.

  • --jsx Le support JSX est fourni par un autre plugin. Si vous souhaitez que votre sortie contienne du code JSX (c'est-à-dire --jsx preserve), vous avez besoin du plugin @babel/plugin-syntax-jsx ; si vous voulez le transpiler en JavaScript standard (c'est-à-dire --jsx react ou --jsx react-native), vous devriez utiliser le plugin @babel/plugin-transform-react-jsx.

  • --jsxFactory Elle peut être personnalisée via l'option pragma du package @babel/plugin-transform-react-jsx. Vous devez également configurer l'option jsxPragma de ce plugin.

  • --module, -m Si vous utilisez un bundler (Webpack ou Rollup), cette option est définie automatiquement. Si vous utilisez @babel/preset-env, vous pouvez utiliser l'option modules ; sinon vous pouvez charger le plugin spécifique.

    Valeur --modulemodules de @babel/preset-envPlugin spécifique
    Nonefalse/
    CommonJS"commonjs" ou "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 ou ES2015false/
  • --outDir Lorsque vous utilisez @babel/cli, vous pouvez configurer l'option --out-dir.

  • --outFile Babel ne prend pas en charge la concaténation de fichiers de sortie : vous devriez utiliser un bundler (comme Webpack, Rollup ou Parcel) pour cela. Lorsque vous utilisez @babel/cli, vous pouvez compiler un seul fichier avec l'option --out-file.

  • --sourceMap Vous pouvez utiliser l'option globale sourceMaps: true.

  • --target Babel ne prend pas en charge le ciblage d'une version spécifique du langage, mais vous pouvez choisir les moteurs à cibler en utilisant @babel/preset-env. Si vous préférez, vous pouvez activer des plugins individuels pour chaque fonctionnalité ECMAScript.

  • --useDefineForClassFields Utilisez l'hypothèse setPublicClassFields pour reproduire ce comportement.

  • --watch, -w Avec @babel/cli, spécifiez l'option --watch.

Mises en garde

Certaines fonctionnalités TypeScript nécessitent le système de typage complet pour effectuer des modifications à l'exécution. Cette section de mises en garde est assez longue, mais notez que plusieurs de ces caractéristiques concernent principalement d'anciennes bases de code TypeScript et possèdent des équivalents JavaScript modernes que vous utilisez probablement déjà.

  1. Comme Babel ne vérifie pas les types, un code syntaxiquement correct mais échouant à la vérification TypeScript peut être transformé avec succès, parfois de manière inattendue ou invalide.

  2. Les modifications de votre tsconfig.json ne sont pas répercutées dans Babel. Le processus de compilation se comportera toujours comme si isolatedModules était activé. Il existe cependant des alternatives natives Babel pour configurer de nombreuses options du tsconfig.json.

  3. Q : Pourquoi Babel n'autorise-t-il pas l'export de var ou let ?

    R : Le compilateur TypeScript adapte dynamiquement l'utilisation de ces variables selon leur mutabilité. Cela dépend d'un modèle de typage hors du champ d'application de Babel. Une implémentation approximative transformerait les usages contextuels de la variable pour toujours utiliser Namespace.Value plutôt que Value, au cas où elle serait modifiée hors du fichier courant. Autoriser var ou let dans Babel (l'implémentation étant manquante) risquerait donc de générer des bugs si utilisé comme s'il ne s'agissait pas de const.

Support Partiel des Namespaces

Si votre code existant utilise les fonctionnalités TypeScript des namespaces, Babel n'en prend en charge qu'un sous-ensemble. Pour du nouveau code utilisant les namespaces, préférez plutôt import/export d'ES2015. Cette fonctionnalité ne disparaît pas, mais des alternatives modernes existent.

  • Les namespace purement typés doivent être marqués avec declare puis seront supprimés.

  • exporter une variable avec var ou let dans un namespace générera une erreur : "L'export de non-const dans les namespaces n'est pas pris en charge par Babel. Utilisez const ou..."

    Solution : Utilisez const. Si une mutation est nécessaire, employez explicitement un objet avec mutabilité interne.

  • Les namespace ne partageront pas leur portée. Dans TypeScript, il est valide de se référer à des éléments contextuels qu'un namespace étend sans les qualifier, et le compilateur ajoutera le qualificatif. Dans Babel, il n'existe pas de modèle de types, et il est impossible de modifier dynamiquement les références pour correspondre au type établi de l'objet parent.

    Considérez ce code :

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

    Le compilateur TypeScript le compile comme ceci :

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

    Tandis que Babel le transformera ainsi :

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

    Comme Babel ne comprend pas le type de N, la référence à V sera undefined, générant une erreur.

    Solution de contournement : Référencez explicitement les valeurs extérieures à la définition actuelle du namespace, même si elles devraient être dans la portée selon TypeScript. Exemples :

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

    Ou :

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