Exportation Typescript vs exportation par défaut
Quelle est la différence de Typescript entre export
et default export
. Dans tous les tutoriels, je vois des gens export
ing leurs classes et je ne peux pas compiler mon code si je n'ajoute pas le mot-clé default
avant d'exporter.
En outre, je n'ai trouvé aucune trace du mot-clé export 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];
}
Si.
L'erreur est: error TS1192: Module '"src/app/MyClass"' has no default export.
3 réponses
D'Exportation 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'une seule exportation par défaut par fichier et que vous l'importez comme suit:
import MyClass from "./MyClass";
Vous pouvez lui donner n'importe quel nom que vous aimez. Par exemple, cela fonctionne bien:
import MyClassAlias from "./MyClass";
Nommé À L'Exportation (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: ajout des accolades va corriger 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, alors vous pouvez importer les deux comme ceci:
import { MyClass, MyOtherClass } from "./MyClass";
// use MyClass and MyOtherClass
Ou vous pouvez leur donner 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 concis parce que leur cas d'utilisation est plus commun; cependant, quand je travaille sur du code interne à un projet en TypeScript, je préfère utiliser des exportations nommées au lieu des exportations par défaut presque tout le temps car cela fonctionne très bien avec le refactoring de code. Par exemple, si vous exportez par défaut une classe et renommez cette classe, elle ne renommera que la classe dans ce fichier et non aucune des autres références dans d'autres fichiers. Avec les exportations nommées, il renommera la classe et toutes les références à cela classe dans tous les autres fichiers.
Il joue également très bien avec barrel files (fichiers qui utilisent namespace exports - 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 lorsqu'il n'y a qu'une seule exportation est contraire au manuel TypeScript -voir la section "drapeaux rouges". Je crois que cette recommandation ne s'applique que lorsque vous créez une API pour d'autres les gens à utiliser et le code n'est pas interne à votre projet. Lorsque je conçois une API pour les gens à utiliser, j'utiliserai une exportation par défaut afin que les gens puissent faire 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
, donc si le fichier a une exportation par défaut ensuite, vous pouvez également importer en faisant:
import { default as MyClass } from "./MyClass";
Et prenez note de ces d'autres façons d'importer existent:
import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports
Voici un exemple avec l'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 (utilisez quand vous ne voulez pas et n'avez pas besoin de créer une nouvelle instance) et ce n'est pas global, vous importerez ceci seulement quand il en a besoin:
import MyScreen from "./module/screen";
console.log( MyScreen.width(100) );
J'essayais de résoudre le MÊME PROBLÈME, MAIS j'ai trouvé un conseil intéressant par Basarat Ali Syed , de TypeScript Deep Dive fame, que nous devrions éviter la déclaration Générique export default
pour une classe, et à la place ajouter la balise export
à la déclaration de classe. La classe importée doit ê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 va importer, on devrait utiliser
export class Foo {
// ...
}
Et import {Foo} from './foo'
dans l'importateur.
La raison en est les difficultés dans le refactoring des classes, et le travail supplémentaire pour l'exportation. Le message original de Basarat est en export default
peut entraîner des problèmes