Quelle est la différence dans TypeScript entre export
et default export
. Dans tous les tutoriels, je vois des personnes export
dans leurs classes et je ne peux pas compiler mon code si je n'ajoute pas le mot clé default
avant l'exportation.
De plus, je n'ai trouvé aucune trace du mot-clé d'exportation par défaut dans la documentation officielle TypeScript .
export class MyClass {
collection = [1,2,3];
}
Ne compile pas. Mais:
export default class MyClass {
collection = [1,2,3];
}
Est-ce que.
L'erreur est: error TS1192: Module '"src/app/MyClass"' has no default export.
Export par défaut (export default
)
// MyClass.ts -- using default export
export default class MyClass { /* ... */ }
La principale différence est que vous ne pouvez avoir qu'un seul export par défaut et que vous l'importez comme ceci:
import MyClass from "./MyClass";
Vous pouvez lui donner n'importe quel nom. Par exemple cela fonctionne bien:
import MyClassAlias from "./MyClass";
Export nommé (export
)
// MyClass.ts -- using named exports
export class MyClass { /* ... */ }
export class MyOtherClass { /* ... */ }
Lorsque vous utilisez une exportation nommée, vous pouvez avoir plusieurs exportations par fichier et vous devez importer les exportations entourées d'accolades:
import { MyClass } from "./MyClass";
Remarque: l'ajout d'accolades résoudra l'erreur que vous décrivez dans votre question et le nom spécifié dans les accolades doit correspondre au nom de l'exportation.
Ou dites que votre fichier a exporté plusieurs} classes, vous pouvez alors importer les deux comme suit:
import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass
Ou vous pouvez donner à l'un d'eux un nom différent dans ce fichier:
import { MyClass, MyOtherClass as MyOtherClassAlias } from "./MyClass";
// use MyClass and MyOtherClassAlias
Ou vous pouvez importer tout ce qui est exporté en utilisant * as
:
import * as MyClasses from "./MyClass";
// use MyClasses.MyClass and MyClasses.MyOtherClass here
Lequel utiliser?
Dans ES6, les exportations par défaut sont concises car leur cas d'utilisation est plus courant ; Cependant, lorsque je travaille sur du code interne à un projet dans TypeScript, je préfère utiliser les exportations nommées plutôt que les exportations par défaut presque tout le temps, car cela fonctionne très bien avec le refactoring de code. Par exemple, si vous exportez une classe par défaut et renommez cette classe, la classe ne sera renommée que dans ce fichier et pas les autres références contenues dans d'autres fichiers. Avec les exportations nommées, il renommera la classe et toutes les références à cette classe dans tous les autres fichiers.
Il joue également très bien avec fichiers barils (fichiers qui utilisent des exportations d'espace de noms --export *
- pour exporter d'autres fichiers). Un exemple de ceci est montré dans la section "exemple" de cette réponse .
Notez que mon opinion sur l’utilisation des exportations nommées même s’il n’ya qu’une exportation va à l’encontre de TypeScript Handbook - voir la section "Drapeaux rouges". Je pense que cette recommandation ne s'applique que lorsque vous créez une API que d'autres personnes peuvent utiliser et que le code n'est pas interne à votre projet. Lorsque je conçois une API que les utilisateurs peuvent utiliser, j'utilise une exportation par défaut afin que les utilisateurs puissent effectuer import myLibraryDefaultExport from "my-library-name";
. Si vous n'êtes pas d'accord avec moi à ce sujet, j'aimerais entendre votre raisonnement.
Cela dit, trouvez ce que vous préférez! Vous pouvez utiliser l'un, l'autre ou les deux en même temps.
Points supplémentaires
Une exportation par défaut est en fait une exportation nommée avec le nom default
. Ainsi, si le fichier a une exportation par défaut, vous pouvez également importer en effectuant les opérations suivantes:
import { default as MyClass } from "./MyClass";
Et notez ces d’autres manières d’importer existent:
import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports
J'essayais de résoudre le même problème, mais j'ai trouvé un conseil intéressant de Basarat ALi Syed , de TypeScript Deep Dive, qu'il fallait éviter la déclaration générique export default
pour une classe et ajouter à la place le export
balise à la déclaration de classe. La classe importée doit plutôt être listée dans la commande import
du module.
C'est-à-dire: au lieu de
class Foo {
// ...
}
export default Foo;
et le simple import Foo from './foo';
dans le module qui importera, il faut utiliser
export class Foo {
// ...
}
et import {Foo} from './foo'
dans l'importateur.
Cela s'explique par les difficultés de refactorisation des classes et par le travail supplémentaire nécessaire à l'exportation. Le message original de Basarat est dans export default
peut poser problème
Voici un exemple d’exportation d’objets simples.
var MyScreen = {
/* ... */
width : function (percent){
return window.innerWidth / 100 * percent
}
height : function (percent){
return window.innerHeight / 100 * percent
}
};
export default MyScreen
Dans le fichier principal (à utiliser quand vous ne voulez pas et n'avez pas besoin de créer une nouvelle instance) et que ce n'est pas global, vous l'importerez seulement quand il le faut
import MyScreen from "./module/screen";
console.log( MyScreen.width(100) );