Was macht 'deklarieren' in 'Export deklarieren Klassenaktionen'?


Antworten:


210

gefunden, wonach ich gesucht habe:

Deklarieren vs. var

varerstellt eine neue Variable. declarewird verwendet, um TypeScript mitzuteilen, dass die Variable an anderer Stelle erstellt wurde. Wenn Sie verwenden declare, wird dem generierten JavaScript nichts hinzugefügt - es ist lediglich ein Hinweis für den Compiler.

Wenn Sie beispielsweise ein externes Skript verwenden, das definiert var externalModule, declare var externalModuleverweisen Sie auf den externalModulebereits eingerichteten TypeScript-Compiler


Ich habe ein ähnliches Szenario mit einem externen JS, der externalModuleunter anderem eine Variable definiert . Was könnte der Grund sein, warum externalModulezur Laufzeit undefiniert ist, einige der anderen Variablen jedoch nicht?
Alejandro González

93

Um dies zu verstehen, müssen Sie zuerst das Schlüsselwort "deklarieren" verstehen.

Hier ist eine gute Erklärung aus Gil Finks Blog :

Das Schlüsselwort TypeScript-Deklaration wird verwendet, um Variablen zu deklarieren, die möglicherweise nicht aus einer TypeScript-Datei stammen.

Stellen wir uns zum Beispiel vor, wir haben eine Bibliothek namens myLibrary ohne TypeScript-Deklarationsdatei und einen Namespace namens myLibrary im globalen Namespace. Wenn Sie diese Bibliothek in Ihrem TypeScript-Code verwenden möchten, können Sie den folgenden Code verwenden:

declare var myLibrary;

Der Typ, den die TypeScript-Laufzeit der Variablen myLibrary gibt, ist ein beliebiger Typ. Das Problem hierbei ist, dass Sie in der Entwurfszeit kein Intellisense für diese Variable haben, aber die Bibliothek in Ihrem Code verwenden können. Eine andere Option, um dasselbe Verhalten ohne Verwendung des Schlüsselworts declare zu erzielen, ist die Verwendung einer Variablen mit einem beliebigen Typ:

var myLibrary: any;

Beide Codebeispiele führen zu derselben JavaScript-Ausgabe, aber das Deklarationsbeispiel ist besser lesbar und drückt eine Umgebungsdeklaration aus.


Nachdem Sie das Schlüsselwort "deklarieren" verstanden haben, kehren Sie dorthin zurück, wo Sie das finden

export declare class Action{
...
}

Die eigentliche Implementierung der Klasse befindet sich wahrscheinlich an einer anderen Stelle - möglicherweise in einer .js-Datei.


2
"Beide Codebeispiele führen zu derselben JavaScript-Ausgabe", das ist nicht wahr: declare var myLibrarywird in nichts
apollo

38

declare im Typoskript:

Das declareSchlüsselwort in Typoskript ist nützlich, um dem Typoskript-Compiler mitzuteilen, dass eine Deklaration an einer anderen Stelle definiert ist (irgendwo in einer externen Javascript-Datei oder einem Teil der Laufzeitumgebung).

Nehmen wir an, wir haben eine Variable namens foo, die woanders deklariert ist. Wenn wir dann versuchen, auf die Variable zu verweisen, gibt der Typoskript-Compiler einen Fehler aus:

foo = 'random'; // Error: 'foo' is not defined

Wir können dieses Problem mit dem beheben declare Schlüsselwort :

declare var foo: string;
foo = 'random';  // no error anymore

Dies hat folgende Konsequenzen:

  • Wann foo tatsächlich nirgendwo anders deklariert wird und wir versuchen, die Variable zu verwenden, kann ein Laufzeitfehler auftreten. Verwenden Sie also nur diedeclare Schlüsselwort wenn Sie wissen, dass die Variable zu diesem Zeitpunkt verfügbar ist.
  • Da wir die Typen kennen, erhalten wir (möglicherweise) Zugriff auf unsere IDE Intellisense .
  • Da wir die Typen kennen, kann der Typoskript-Compiler die Typen zur Kompilierungszeit überprüfen und uns warnen, wenn wir in bestimmten Szenarien die falschen Typen verwenden.

17

Das Schlüsselwort declare in diesem speziellen Fall:

export declare class Actions {
    ...
}

... ist anscheinend nutzlos und ich denke, TypeScript sollte in Betracht ziehen, dies zu einem Fehler zu machen (ich weiß nicht, ob es einen versteckten Grund gibt). Wenn Sie eine Klasse deklarieren, müssen Sie sie niemals importieren. Wenn Sie eine Klasse exportieren, die erwartet, dass jemand sie importiert, müssen Sie sie nicht deklarieren. Und weil Sie diese Klasse deklarieren, sollte diese Klasse per Definition verwendbar sein, ohne dass sie importiert werden muss. Dies gilt jedoch nicht, wenn Sie beim Exportieren eine Klasse deklarieren . Sie müssen es importieren, um es verwenden zu können.

TL; DR

export declare class Actions {
    ...
}

ist das gleiche wie

declare class Actions {
    ...
}

Ich denke nicht, dass sie gleich sind, die ersteren müssen verwendet werden import, die letzteren nicht
Ian Zhong

10

declare - ohne Import- oder Exportschlüsselwörter - Definiert Deklarationsdateien, die automatisch von TypeScript ausgewählt werden. Dies ist eine nützliche Funktion, um älteren Modulen (npm installierte Pakete ohne TypeScript-Definitionen) eine Eingabe hinzuzufügen.

import /. export ist der richtige Weg, um Module zu verwenden, und alles muss manuell (und ich finde es etwas mühsam) importiert werden, entweder es ist Logik, oder es sind Definitionen.

export declareErmöglicht es Ihnen als praktischen Anwendungsfall, das Exportieren aller Unterelemente zu vermeiden, z.

export declare namespace Redux {
    namespace Store {
        interface Definition { ... }
    }
}

Was vielleicht leichter zu lesen ist als:

export namespace Redux {
    export namespace Store {
        export interface Definition { ... }
    }
}

Der externe Import ist in beiden Fällen gleich (z import { Redux } from 'definitions/redux'; ), was ich nicht weiß, ob es sich um eine gute Praxis handelt oder nicht, aber ich finde es ordentlich! ^^

Es ist wichtig zu beachten, dass das Hinzufügen eines importoder exportzu Ihrer Datei dazu führt, dass sie zu einem Modul wird. Daher liegt der declareUmfang nicht mehr auf globaler Ebene.

PS, es gibt einen Fehler ( Problem 16671 ): Wenn Sie const enumin Ihrer Deklaration (ich mache das für den Redux- Aktionstyp ) das transpileOnlyFlag angeben (das Paket create-react-app-typescript , das weiß ich), das Aufzählung wird nicht eingefügt! Sie können darin laufen, Sie können nicht, aber es ist nützlich, vorher zu wissen!


Namespaces in Modulen export namespacesind keine gute Idee und fügen unnötige Namespaces hinzu . In Bezug auf export declare, einen Blick auf André Pena Antwort hat.
Ford04
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.