Zweck des Deklarierens des Schlüsselworts in TypeScript


74

Was ist der Zweck des declareSchlüsselworts?

type Callback = (err: Error | String, data: Array<CalledBackData>) => void;

vs.

declare type Callback = (err: Error | String, data:Array<CalledBackData>) => void;

Es können keine Dokumente gefunden werden, die den Zweck des declareSchlüsselworts in TS erläutern .

Antworten:


87

Hier ist ein Beispiel aus der Praxis.

Ich habe eine TypeScript React-App, die die Webpack Hot Middleware verwendet. Die Webpack Hot Middleware ist nicht in TypeScript geschrieben, sondern in altmodischem JavaScript. Es gibt also keine Typdeklarationen, anhand derer der TypeScript-Compiler prüfen kann.

Wenn ich meinen Code ausführe, ist das Objekt moduleaus der Webpack Hot Middleware vorhanden, und ich kann es konsolen.loggen, obwohl es sich um gutes altmodisches JavaScript handelt, das sich in meiner schicken neuen TypeScript React-App versteckt.

Das moduleObjekt verfügt auch über Schlüssel, z. B. module.hot, und die Schlüssel können Werte haben. Der TypeScript-Entwurfszeit-Compiler (zumindest in VSCode) zeichnet jedoch ein rotes Schnörkel darunter property 'hot' does not exist. Aber es existiert!

Deklarieren Sie den TypeScript-Compiler folgendermaßen, damit er zustimmt:

declare let module: any

Das vorhandene moduleObjekt hat jetzt einen Typ von any, der den TypeScript-Compiler jetzt glücklich macht, rot verschnörkelt und jetzt kann ich meinen anderen Code weiter kompilieren und schreiben.

Wenn Sie das Schlüsselwort entfernen declareund nur schreiben let module: any, wird es nicht kompiliert, sondern sagt dies 'module' already exists. Das ist es, was "Umgebung" in der akzeptierten Antwort bedeutet.


16
declareGibt einen Typ für eine bereits vorhandene Variable an, ohne eine neue zu deklarieren.
Danon

45

tl; dr

'declare' wird verwendet, um dem Compiler mitzuteilen, dass 'dieses Ding (normalerweise eine Variable) bereits existiert und daher von anderem Code referenziert werden kann. Außerdem ist es nicht erforderlich, diese Anweisung in JavaScript zu kompilieren. "

Häufiger Anwendungsfall:

Sie fügen einer JavaScript-Datei, von der der Compiler nichts weiß, einen Verweis auf Ihre Webseite hinzu. Vielleicht ist es ein Skript, das von einer anderen Domain wie 'foo.com' stammt. Bei der Auswertung erstellt und widerspricht das Skript einigen nützlichen API-Methoden und weist sie dem Bezeichner 'fooSdk' im globalen Bereich zu.

Sie möchten, dass Ihr TypeScript-Code 'fooSdk.doSomething ()' aufrufen kann. Da Ihr Compiler jedoch nicht weiß, dass diese Variable vorhanden ist, wird ein Kompilierungsfehler angezeigt.

Anschließend verwenden Sie das Schlüsselwort deklarieren, um dem Compiler mitzuteilen, dass "Vertrauen Sie mir, diese Variable existiert und diesen Typ hat". Der Compiler verwendet diese Anweisung, um anderen Code statisch zu überprüfen, kompiliert ihn jedoch nicht in JavaScript in der Ausgabe.

declare const fooSdk = { doSomething: () => boolean };

Auf die gleiche Weise können Sie das Schlüsselwort declare zu Klasseneigenschaften hinzufügen, um den Compiler anzuweisen, keinen Code auszugeben, der diese Eigenschaft erstellen würde, vorausgesetzt, Sie haben Ihren eigenen Code, der sie erstellt, den der Compiler nicht kennt oder nicht versteht.

Ihr spezifisches Beispiel ist anders, da Sie einen Typ deklarieren, keine Variable. Typen werden bereits in kein JavaScript kompiliert. Ich weiß nicht, ob es einen Grund gibt, einen Typ zu deklarieren.


2

Aus Typoskript-Dokumenten:

Typoskript - Arbeiten mit anderen JavaScript-Bibliotheken

Um die Form von Bibliotheken zu beschreiben, die nicht in TypeScript geschrieben sind, müssen wir die API deklarieren, die die Bibliothek verfügbar macht. Da die meisten JavaScript-Bibliotheken nur wenige Objekte der obersten Ebene verfügbar machen, sind Namespaces eine gute Möglichkeit, sie darzustellen.

Wir nennen Deklarationen, die keine Implementierung definieren, "Ambient". In der Regel werden diese in .d.ts-Dateien definiert. Wenn Sie mit C / C ++ vertraut sind, können Sie sich diese als .h-Dateien vorstellen. Schauen wir uns einige Beispiele an.

Umgebungs-Namespaces

Die beliebte Bibliothek D3 definiert ihre Funktionalität in einem globalen Objekt namens d3. Da diese Bibliothek über ein Tag (anstelle eines Modulladeprogramms) geladen wird, verwendet ihre Deklaration Namespaces, um ihre Form zu definieren. Damit der TypeScript-Compiler diese Form sehen kann, verwenden wir eine Umgebungs-Namespace-Deklaration. Zum Beispiel könnten wir anfangen, es wie folgt zu schreiben:

D3.d.ts (vereinfachter Auszug)

declare namespace D3 {
    export interface Selectors {
        select: {
            (selector: string): Selection;
            (element: EventTarget): Selection;
        };
    }
    // (...)
}

1

delcare-Schlüsselwörter werden verwendet, wenn Sie eine Bibliothek importieren, für die keine Deklarationstypdateien vorhanden sind, z. B. * .d.ts

danach vs eslint nicht die Syntax und den Kontext überprüfen, lassen Sie, wenn Sie standardmäßig tsc Compiler verwenden, dass der gute Grund zu deklarieren, um Syntaxfehler zu entfernen


0

Sie können declare verwenden, um den Compiler über Typen zu informieren, bevor Sie Implementierungscode schreiben, und TypeScript wird sich freuen.

declare function foo(name: string): string
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.