Exportación de tipografía frente a exportación predeterminada

¿Cuál es la diferencia en Typescript entre export y default export ? En todos los tutoriales veo que las personas export sus clases y no puedo comstackr mi código si no agrego la palabra clave default antes de exportar.

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

 export class MyClass { collection = [1,2,3]; } 

No comstack Pero:

 export default class MyClass { collection = [1,2,3]; } 

Hace.

El error es: error TS1192: Module '"src/app/MyClass"' has no default export.

Exportar por defecto ( export default )

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

La principal diferencia es que solo puede tener una exportación predeterminada por archivo y la importa de la siguiente manera:

 import MyClass from "./MyClass"; 

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

 import MyClassAlias from "./MyClass"; 

Nombrado Exportar ( export )

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

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

 import { MyClass } from "./MyClass"; 

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

O diga que su archivo exportó varias clases, entonces podría importar las dos cosas así:

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

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

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

O bien, puede importar todo lo que se exporta utilizando * 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 estoy trabajando en el código interno de un proyecto en TypeScript, prefiero usar las exportaciones con nombre en lugar de las exportaciones predeterminadas casi todo el tiempo porque funciona muy bien con la refactorización del código. Por ejemplo, si exporta una clase por defecto y cambia el nombre de esa clase, solo cambiará el nombre de la clase en ese archivo y no de las otras referencias 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 los archivos de barril (archivos que usan exportes de espacios de nombres export- 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 “Banderas rojas”. Creo que esta recomendación solo se aplica cuando está creando una API para que otras personas la utilicen y el código no es interno a su proyecto. Cuando estoy diseñando una API para que las personas la usen, import myLibraryDefaultExport from "my-library-name"; una exportación predeterminada para que la gente pueda import myLibraryDefaultExport from "my-library-name"; . Si no está de acuerdo conmigo sobre hacer esto, me encantaría escuchar su razonamiento.

Dicho eso, encuentra lo que prefieres! Podrías usar uno, el otro o ambos al mismo tiempo.

Puntos adicionales

Una exportación predeterminada es en realidad una exportación con nombre con el 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 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 

Aquí hay un ejemplo con la exportación de objetos simples.

 var MyScreen = { /* ... */ width : function (percent){ return window.innerWidth / 100 * percent } height : function (percent){ return window.innerHeight / 100 * percent } }; export default MyScreen 

En el archivo principal (Utilícelo cuando no desee y no necesite crear una nueva instancia) y no sea global, lo importará solo cuando lo necesite:

 import MyScreen from "./module/screen"; console.log( MyScreen.width(100) ); 

Estaba tratando de resolver el mismo problema, pero encontré un consejo interesante de Basarat Ali Syed , de la fama de TypeScript Deep Dive , de que debemos evitar la statement genérica de export default para una clase y, en su lugar, anexar la etiqueta de export a la statement de clase. La clase importada debe aparecer en su lugar en el comando de import del módulo.

Es decir: en lugar de

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

y la simple import Foo from './foo'; en el módulo que importará, uno debería usar

 export class Foo { // ... } 

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

El motivo es la dificultad en la refacturación de las clases y el trabajo adicional para la exportación. La publicación original de Basarat está en export default puede ocasionar problemas