Exportación de TypeScript frente a exportación predeterminada

Resuelto fos.alex asked hace 9 años • 4 respuestas

¿Cuál es la diferencia en TypeScript entre exporty default export?

En todos los tutoriales, veo personas exportparticipando en sus clases y no puedo compilar mi código si no agrego la defaultpalabra clave antes de exportar.

Además, no pude encontrar ningún rastro de la palabra clave de exportación predeterminada en la documentación oficial de TypeScript .

export class MyClass {

  collection = [1,2,3];

}

No compila. Pero:

export default class MyClass {

  collection = [1,2,3];

}

Hace.

El error es:

error TS1192: El módulo '"src/app/MyClass"' no tiene exportación predeterminada.

fos.alex avatar Oct 23 '15 22:10 fos.alex
Aceptado

Exportación predeterminada ( export default)

// MyClass.ts -- using default export
export default class MyClass { /* ... */ }

La principal diferencia es que solo puedes tener una exportación predeterminada por archivo y la importas así:

import MyClass from "./MyClass";

Puedes darle el nombre que quieras. Por ejemplo esto funciona bien:

import MyClassAlias from "./MyClass";

Exportación con nombre ( export)

// MyClass.ts -- using named exports
export class MyClass { /* ... */ }
export class MyOtherClass { /* ... */ }

Cuando utiliza una exportación con nombre, puede tener múltiples exportaciones por archivo y necesita importar las exportaciones entre llaves:

import { MyClass } from "./MyClass";

Nota: Agregar las llaves solucionará el error que estás describiendo en tu pregunta y el nombre especificado entre las llaves debe coincidir con el nombre de la exportación.

O digamos que su archivo exportó varias clases, luego podría importar ambas así:

import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass

O podrías darles a cualquiera de ellos un nombre diferente en este archivo:

import { MyClass, MyOtherClass as MyOtherClassAlias } from "./MyClass";
// use MyClass and MyOtherClassAlias

O puedes importar todo lo que se exporta usando * as:

import * as MyClasses from "./MyClass";
// use MyClasses.MyClass and MyClasses.MyOtherClass here

¿Cuál usar?

En ES6, las exportaciones predeterminadas son concisas porque su caso de uso es más común ; sin embargo, cuando trabajo en código interno de un proyecto en TypeScript, prefiero usar exportaciones con nombre en lugar de exportaciones predeterminadas casi todo el tiempo porque funciona muy bien con la refactorización de código. Por ejemplo, si exporta una clase de forma predeterminada y le cambia el nombre, solo cambiará el nombre de la clase en ese archivo y no de ninguna otra referencia en otros archivos. Con las exportaciones con nombre, cambiará el nombre de la clase y todas las referencias a esa clase en todos los demás archivos.

También funciona muy bien con archivos barril (archivos que utilizan exportaciones de espacios de nombres export *para exportar otros archivos). Un ejemplo de esto se muestra en la sección "ejemplo" de esta respuesta .

Tenga en cuenta que mi opinión sobre el uso de exportaciones con nombre incluso cuando solo hay una exportación es contraria al Manual de TypeScript ; consulte la sección "Señales de alerta". Creo que esta recomendación solo se aplica cuando estás creando una API para que la usen otras personas y el código no es interno a tu proyecto. Cuando diseño una API para que la use la gente, usaré una exportación predeterminada para que la gente pueda hacer import myLibraryDefaultExport from "my-library-name";. Si no está de acuerdo conmigo acerca de hacer esto, me encantaría escuchar su razonamiento.

Dicho esto, ¡encuentra lo que prefieras! Podrías utilizar uno, el otro o ambos al mismo tiempo.

Puntos adicionales

Una exportación predeterminada es en realidad una exportación con nombre default, por lo que si el archivo tiene una exportación predeterminada, también puede importar haciendo:

import { default as MyClass } from "./MyClass";

Y tenga en cuenta que existen estas otras formas de importar: 

import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports
David Sherret avatar Oct 23 '2015 16:10 David Sherret

Estaba tratando de resolver el mismo problema, pero encontré un consejo interesante de Basarat Ali Syed , famoso por TypeScript Deep Dive , de que deberíamos evitar la export defaultdeclaración genérica para una clase y, en su lugar, agregar la exportetiqueta a la declaración de clase. En cambio, la clase importada debería aparecer en el importcomando del módulo.

Es decir: en lugar de

class Foo {
    // ...
}
export default Foo;

y el simple import Foo from './foo';en el módulo que importará, se debe usar

export class Foo {
    // ...
}

y import {Foo} from './foo'en el importador.

La razón de esto son las dificultades en la refactorización de clases y el trabajo adicional para la exportación. La publicación original de Basarat está en Evitar exportación predeterminada

Hilton Fernandes avatar May 10 '2018 20:05 Hilton Fernandes

Exportación nombrada

En TypeScript puedes exportar con la exportpalabra clave. Luego se puede importar mediante import {name} from "./mydir";. Esto se llama exportación con nombre . Un archivo puede exportar varias exportaciones con nombre. Además, los nombres de las importaciones deben coincidir con los de las exportaciones. Por ejemplo:

// foo.js file
export class foo{}
export class bar{}

// main.js file in same dir
import {foo, bar} from "./foo";

La siguiente sintaxis alternativa también es válida:

// foo.js file
function foo() {};
function bar() {};
export {foo, bar};

// main.js file in same directory
import {foo, bar} from './foo'

Exportación predeterminada

También podemos usar una exportación predeterminada . Solo puede haber una exportación predeterminada por archivo. Al importar una exportación predeterminada, omitimos los corchetes en la declaración de importación. También podemos elegir nuestro propio nombre para nuestra importación.

// foo.js file
export default class foo{}

// main.js file in same directory
import abc from "./foo";

Es solo JavaScript

Los módulos y sus palabras clave asociadas como import, exporty export defaultson construcciones de JavaScript, no de TypeScript. Sin embargo, TypeScript le agregó la exportación e importación de interfaces y alias de tipos.

Willem van der Veen avatar Oct 31 '2020 11:10 Willem van der Veen