Saltar al contenido principal

@babel/plugin-transform-typescript

Traducción Beta No Oficial

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

información

Este plugin está incluido en @babel/preset-typescript

Este plugin añade soporte para la sintaxis de tipos utilizada por el lenguaje de programación TypeScript. Sin embargo, este plugin no añade la capacidad de verificación de tipos del JavaScript que se le pasa. Para eso, necesitarás instalar y configurar TypeScript.

Ten en cuenta que aunque el compilador de TypeScript tsc admite activamente ciertas propuestas de JavaScript como el encadenamiento opcional (?.), el operador de coalescencia nula (??) y las propiedades de clase (this.#x), este preset no incluye estas características porque no son parte de la sintaxis de tipos exclusiva de TypeScript. Recomendamos usar preset-env junto con preset-typescript si deseas transpilar estas características.

Ejemplo

Entrada

const x: number = 0;

Salida

const x = 0;

Instalación

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

Uso

Mediante un archivo de configuración (Recomendado)

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

Mediante la CLI

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

Mediante la API de Node

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

Opciones

allowDeclareFields

boolean, valor predeterminado: false

Añadido en v7.7.0

nota

Estará habilitado por defecto en Babel 8

Cuando está habilitado, los campos de clase exclusivamente de tipo solo se eliminan si están prefijados con el modificador declare:

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

allowNamespaces

boolean, valor predeterminado: true.

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

Habilita la compilación de espacios de nombres (namespaces) de TypeScript.

disallowAmbiguousJSXLike

boolean, valor predeterminado: false

Añadido en: v7.16.0

Incluso cuando el análisis de JSX no está activado, esta opción prohíbe el uso de sintaxis que sería ambigua con JSX (afirmaciones de tipo <X> y y argumentos de tipo <X>() => {}). Coincide con el comportamiento de tsc al analizar archivos .mts y .mjs.

dts

boolean, valor predeterminado: false

Añadido en: v7.20.0

Esta opción habilita el análisis dentro de un contexto ambiental de TypeScript, donde ciertas sintaxis tienen reglas diferentes (como archivos .d.ts y bloques declare module). Consulta el Manual Oficial y TypeScript Deep Dive para más información sobre contextos ambientales.

isTSX

boolean, valor predeterminado: false

Habilita forzosamente el análisis de jsx. De lo contrario, los corchetes angulares se interpretarán como la aserción de tipo heredada de TypeScript var foo = <string>bar;. Además, isTSX: true requiere allExtensions: true.

jsxPragma

string, valor predeterminado: React.createElement

Reemplaza la función utilizada al compilar expresiones JSX. Esto permite identificar que la importación no es de tipo y no debe eliminarse.

jsxPragmaFrag

string, valor predeterminado: React.Fragment

Reemplaza la función utilizada al compilar expresiones de fragmentos JSX. Esto permite identificar que la importación no es de tipo y no debe eliminarse.

onlyRemoveTypeImports

boolean, valor predeterminado: false

Añadido en: v7.9.0

Cuando se establece en true, la transformación solo eliminará importaciones solo de tipo (introducidas en TypeScript 3.8). Solo debe usarse si utilizas 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, valor predeterminado: false

Añadido en: v7.15.0

Cuando se establece en true, Babel insertará en línea los valores de la enumeración en lugar de usar la salida enum habitual:

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

Esta opción difiere del comportamiento de --isolatedModules de TypeScript, que ignora el modificador const y los compila como enumeraciones normales, alineando el comportamiento de Babel con el funcionamiento predeterminado de TypeScript.

Sin embargo, al exportar un const enum, Babel lo compilará como un objeto literal simple para evitar depender de análisis entre archivos:

// Input
export const enum Animals {
Fish,
}

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

Opciones del Compilador de TypeScript

El compilador oficial de TypeScript tiene muchas opciones para configurar cómo compila y verifica tipos. Aunque muchas no aplican, algunos comportamientos pueden ser útiles y sus equivalentes en Babel pueden habilitarse mediante opciones de configuración o plugins.

  • --alwaysStrict Puedes usar la opción del parser strictMode:

    JavaScript
    module.exports = {
    parserOpts: { strictMode: true },
    };
  • --downlevelIteration Puedes usar el plugin @babel/plugin-transform-for-of. Si usas @babel/preset-env, for...of ya se transpila usando iteradores cuando no es compatible con tu(s) objetivo(s) de compilación.

  • --emitDecoratorMetadata Esta opción no es compatible con paquetes oficiales de Babel ya que es una adición específica de TypeScript y no forma parte de la propuesta de decoradores. Si dependes de esta característica, puedes usar el plugin comunitario babel-plugin-transform-typescript-metadata.

  • --esModuleInterop Este es el comportamiento predeterminado de Babel al transpilar módulos ECMAScript.

  • --experimentalDecorators Esta opción habilita soporte para la propuesta de decoradores "legacy". Puedes habilitarla en Babel usando el plugin @babel/plugin-proposal-decorators, pero ten en cuenta que existen algunas diferencias menores.

    JavaScript
    module.exports = {
    plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
    };
  • --importHelpers Esto es equivalente al paquete @babel/plugin-transform-runtime.

  • ---importsNotUsedAsValues Puedes usar la opción onlyRemoveTypeImports para replicar este comportamiento. onlyRemoveTypeImports: true equivale a importsNotUsedAsValues: preserve, mientras que onlyRemoveTypeImports: false equivale a importsNotUsedAsValues: remove. No existe equivalente para importsNotUsedAsValues: error.

  • --inlineSourceMap Puedes configurar la opción sourceMaps: "inline" en tu archivo babel.config.json.

  • --isolatedModules Este es el comportamiento predeterminado de Babel, y no puede desactivarse porque Babel no admite análisis entre archivos.

  • --jsx El soporte para JSX se proporciona mediante otro plugin. Si quieres que tu salida contenga código JSX (es decir, --jsx preserve), necesitas el plugin @babel/plugin-syntax-jsx; si quieres transpilarlo a JavaScript estándar (es decir, --jsx react o --jsx react-native), deberías usar el plugin @babel/plugin-transform-react-jsx.

  • --jsxFactory Puede personalizarse usando la opción pragma del paquete @babel/plugin-transform-react-jsx. También necesitas configurar la opción jsxPragma de este plugin.

  • --module, -m Si usas un empaquetador (Webpack o Rollup), esta opción se establece automáticamente. Si usas @babel/preset-env, puedes usar la opción modules; de lo contrario puedes cargar el plugin específico.

    Valor de --modulemodules de @babel/preset-envPlugin individual
    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 Cuando usas @babel/cli, puedes establecer la opción --out-dir.

  • --outFile Babel no admite concatenar archivos de salida: para eso deberías usar un empaquetador (como Webpack, Rollup o Parcel). Cuando usas @babel/cli, puedes compilar un solo archivo usando la opción --out-file.

  • --sourceMap Puedes usar la opción de nivel superior sourceMaps: true.

  • --target Babel no permite apuntar a una versión específica del lenguaje, pero puedes elegir qué motores quieres compatibilizar usando @babel/preset-env. Si lo prefieres, puedes habilitar plugins individuales para cada característica de ECMAScript.

  • --useDefineForClassFields Puedes usar la asunción setPublicClassFields para replicar este comportamiento.

  • --watch, -w Cuando uses @babel/cli, puedes especificar la opción --watch.

Advertencias

Esto se debe a que existen características de TypeScript que dependen del sistema de tipos completo para realizar cambios en tiempo de ejecución. Esta sección de advertencias es bastante extensa, aunque cabe destacar que varias de estas características solo se encuentran en bases de código TypeScript antiguas y tienen equivalentes modernos en JavaScript que probablemente ya uses.

  1. Como Babel no realiza comprobación de tipos, el código que es sintácticamente correcto pero que fallaría en la verificación de tipos de TypeScript podría transformarse con éxito, a menudo de formas inesperadas o inválidas.

  2. Los cambios en tu tsconfig.json no se reflejan en Babel. El proceso de compilación siempre se comportará como si isolatedModules estuviera activado. Sin embargo, existen alternativas nativas de Babel para configurar muchas de las opciones de tsconfig.json.

  3. P: ¿Por qué Babel no permite exportar var o let?

    R: El compilador de TypeScript cambia dinámicamente cómo se usan estas variables dependiendo de si su valor se muta o no. Esto depende de un modelo de tipos y está fuera del alcance de Babel. Una implementación de mejor esfuerzo transformaría los usos dependientes del contexto para usar siempre Namespace.Value en lugar de Value, en caso de que la variable fuera mutada fuera del archivo actual. Permitir var o let en Babel (dado que esta transformación aún no está implementada) es más probable que se manifieste como un error cuando se usa como si no fuera const.

Soporte Parcial para Namespaces

Si tienes código existente que usa las características exclusivas de TypeScript para namespaces, Babel admite un subconjunto de ellas. Si estás considerando escribir nuevo código que use namespaces, se recomienda usar import/export de ES2015 en su lugar. No desaparecerán, pero existen alternativas modernas.

  • Los namespace exclusivamente de tipo deben marcarse con declare y posteriormente se eliminarán de forma segura.

  • exportar una variable usando var o let en un namespace resultará en un error: "Babel no admite namespaces que exportan variables no constantes. Cambia a const o..."

    Solución alternativa: Usa const. Si se requiere alguna forma de mutación, usa explícitamente un objeto con mutabilidad interna.

  • Los namespace no compartirán su ámbito. En TypeScript es válido referirse a elementos contextuales que un namespace extiende sin calificarlos, y el compilador agregará el calificador. En Babel no existe un modelo de tipos, y es imposible cambiar dinámicamente las referencias para que coincidan con el tipo establecido del objeto padre.

    Considere este código:

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

    El compilador de TypeScript lo compila a algo así:

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

    Mientras que Babel lo transformará a algo como esto:

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

    Como Babel no comprende el tipo de N, la referencia a V será undefined resultando en un error.

    Solución alternativa: Refiera explícitamente a valores que no estén en la misma definición de namespace, incluso si estarían en el ámbito según TypeScript. Ejemplos:

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

    O:

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