Typoskript-Export vs. Standardexport


272

Was ist der Unterschied in Typescript zwischen exportund default export. In allen Tutorials sehe ich Leute in exportihren Klassen und ich kann meinen Code nicht kompilieren, wenn ich das defaultSchlüsselwort vor dem Export nicht hinzufüge .

Außerdem konnte ich in der offiziellen Typoskript-Dokumentation keine Spur des Standardexport-Schlüsselworts finden .

export class MyClass {

  collection = [1,2,3];

}

Kompiliert nicht. Aber:

export default class MyClass {

  collection = [1,2,3];

}

Tut.

Der Fehler ist: error TS1192: Module '"src/app/MyClass"' has no default export.



3
Einige leichte Lektüre zum Thema. Es kann hilfreich sein, wenn Sie zeigen, wie Sie diese Klasse importieren. Ich glaube, hier tritt der Fehler auf (wahrscheinlich müssen Sie die Importsyntax ändern, um das Fehlerszenario zu beheben).
Sunil D.

5
"export" und "export default" sind überhaupt kein TypeScript - sie sind ES6.
Sensei James

Antworten:


458

Standardexport ( export default)

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

Der Hauptunterschied besteht darin, dass Sie nur einen Standardexport pro Datei haben können und diesen wie folgt importieren:

import MyClass from "./MyClass";

Sie können ihm einen beliebigen Namen geben. Zum Beispiel funktioniert das gut:

import MyClassAlias from "./MyClass";

Benannter Export ( export)

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

Wenn Sie einen benannten Export verwenden, können Sie mehrere Exporte pro Datei durchführen und die Exporte in geschweiften Klammern importieren:

import { MyClass } from "./MyClass";

Hinweis: Durch Hinzufügen der geschweiften Klammern wird der Fehler behoben, den Sie in Ihrer Frage beschreiben, und der in den geschweiften Klammern angegebene Name muss mit dem Namen des Exports übereinstimmen.

Oder sagen Sie, Ihre Datei hat mehrere Klassen exportiert , dann können Sie beide wie folgt importieren:

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

Oder Sie können einem von ihnen in dieser Datei einen anderen Namen geben:

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

Oder Sie können alles, was exportiert wird, importieren, indem Sie Folgendes verwenden * as:

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

Welche verwenden?

In ES6 sind Standardexporte präzise, ​​da ihr Anwendungsfall häufiger vorkommt . Wenn ich jedoch an projektinternem Code in TypeScript arbeite, bevorzuge ich fast immer benannte Exporte anstelle von Standardexporten, da dies sehr gut mit Code-Refactoring funktioniert. Wenn Sie beispielsweise standardmäßig eine Klasse exportieren und diese Klasse umbenennen, wird nur die Klasse in dieser Datei umbenannt und keine der anderen Referenzen in anderen Dateien. Bei benannten Exporten werden die Klasse und alle Verweise auf diese Klasse in allen anderen Dateien umbenannt.

Es spielt sich auch sehr gut mit Barrel-Dateien (Dateien, die Namespace-Exporte verwenden export *- um andere Dateien zu exportieren). Ein Beispiel hierfür finden Sie im Abschnitt "Beispiel" dieser Antwort .

Beachten Sie, dass meine Meinung zur Verwendung benannter Exporte, auch wenn es nur einen Export gibt, im Widerspruch zum TypeScript-Handbuch steht - siehe Abschnitt "Rote Flaggen". Ich glaube, diese Empfehlung gilt nur, wenn Sie eine API für andere Personen erstellen und der Code nicht projektintern ist. Wenn ich eine API für Benutzer entwerfe, verwende ich einen Standardexport, damit Benutzer dies tun können import myLibraryDefaultExport from "my-library-name";. Wenn Sie mir diesbezüglich nicht zustimmen, würde ich gerne Ihre Argumentation hören.

Das heißt, finden Sie, was Sie bevorzugen! Sie können das eine, das andere oder beide gleichzeitig verwenden.

Zusätzliche Punkte

Ein Standardexport ist eigentlich ein benannter Export mit dem Namen default. Wenn die Datei also einen Standardexport hat, können Sie auch Folgendes importieren:

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

Beachten Sie auch, dass es folgende andere Importmöglichkeiten gibt: 

import MyDefaultExportedClass, { Class1, Class2 } from "./SomeFile";
import MyDefaultExportedClass, * as Classes from "./SomeFile";
import "./SomeFile"; // runs SomeFile.js without importing any exports

3
Was ist mit import myAlias = require("./PathToFile")und export = IInterfaceOrClassin der Datei passiert ? Ist das jetzt altmodisch?
BenCr

@ BenCr ja, das ist der neue es6 Weg
David Sherret

Warum geben Sie kein Beispiel für einen "Named Export"?
Stato Machino

aws-sdk / clients / sns hat keine Standardexporte und wenn ich mit import sns von '/ sns' auf sns zugreife, bekomme ich keinen Export, aber der Import myAlias ​​= require ("./ PathToFile") funktioniert. Kann ich etwas ändern, um Sns aus '/ sns' zu importieren, ohne Änderungen an der Quelle vorzunehmen?
Jeson Dias

Wenn Sie das Schlüsselwort nicht explizit defaulteingeben, ist in dieser Datei immer noch ein Standardexport verfügbar? Wenn ja, wie lauten die Regeln?
Simon_Weaver

10

Ich habe versucht, das gleiche Problem zu lösen, fand aber einen interessanten Rat von Basarat Ali Syed von TypeScript Deep Dive , dass wir die generische export defaultDeklaration für eine Klasse vermeiden und stattdessen das exportTag an die Klassendeklaration anhängen sollten . Die importierte Klasse sollte stattdessen im importBefehl des Moduls aufgeführt werden.

Das heißt: statt

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

und das einfache import Foo from './foo';in dem Modul, das importiert werden soll, sollte man verwenden

export class Foo {
    // ...
}

und import {Foo} from './foo'im Importeur.

Der Grund dafür sind Schwierigkeiten bei der Umgestaltung von Klassen und die zusätzliche Arbeit für den Export. Der ursprüngliche Beitrag von Basarat export defaultkann zu Problemen führen


0

Hier ist ein Beispiel für den einfachen Objektexport.

var MyScreen = {

    /* ... */

    width : function (percent){

        return window.innerWidth / 100 * percent

    }

    height : function (percent){

        return window.innerHeight / 100 * percent

    }


};

export default MyScreen

In der Hauptdatei (Verwenden Sie diese Option, wenn Sie keine neue Instanz erstellen möchten und müssen) und wenn diese nicht global ist, wird sie nur dann importiert, wenn sie benötigt wird:

import MyScreen from "./module/screen";
console.log( MyScreen.width(100) );
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.