Ich arbeite mit TypeScript + React + Webpack + Jest + Enzyme.
Ich habe das Bedürfnis, einige globale Funktionen in meinen Testspezifikationen verfügbar zu haben. Ich kann das tun, indem ich die Option setupTestFrameworkScriptFile
in der Jest-Konfiguration auf ein% co_de zeige % Datei und ich habe so etwas:
Auf meinen Spezifikationsdateien kann ich .js
aufrufen und es wird gut funktionieren, wenn ich die Tests durchführe. Aber mein Editor erkennt die Funktion nicht.
Um das zu umgehen, habe ich eine mountWithContext()
-Datei damit erstellt:
Jetzt erkennen meine Spezifikationsdateien die Funktion /typings/declarations.d.ts
, aber die Typen sind "falsch". Die richtige Definition wäre etwa so:
Die mountWithContext
wird korrekt identifiziert, weil die React.ReactElement
-Datei folgendes enthält:
Das Gleiche gilt nicht für Enzyme. Es wird kein globales @types/react/index.d.ts
exportiert. Wenn Sie Enzyme
betrachten, gibt es so etwas:
Aber selbst wenn ich das tue:
%Vor% Es funktioniert nicht. @types/enzyme/index.d.ts
wird immer noch nicht erkannt.
Ich habe versucht, in diese ReactWrapper
-Datei zu importieren, und damit kann ich den Typ korrekt verwenden, aber meine Funktionsdeklaration wird in meinen Spezifikationsdateien nicht mehr erkannt. Ich habe auch versucht, eine Dreifach-Schrägstrich-Direktive wie folgt hinzuzufügen:
Und die Datei wird erkannt, aber der declarations.d.ts
-Typ ist immer noch nicht.
So ... Wie kann ich eine TypeScript-Funktionsdeklaration für meine benutzerdefinierte ReactWrapper
globale Funktion mit allen geeigneten Typen haben, so:
Wenn wir deklarieren möchten, dass die Funktion global.mountWithContext
existiert und den angegebenen Typ hat, können wir zu einer leeren Deklarationsdatei in unserem Projekt Folgendes hinzufügen:
Details
Hier ist eine Aufschlüsselung jedes der oben genannten Konstrukte:
Der declare global
-Block: Der Zweck dieses Konstrukts besteht darin, den globalen Gültigkeitsbereich zu ändern, entweder durch Einführung neuer Deklarationen oder durch Änderung bestehender, von innerhalb ein nicht globaler Kontext wie ein Modul. Unsere Deklarationsdatei ist ein Modul, da sie eine Top-Level import
-Klausel enthält, die ReactWrapper
von Enzyme importiert.
Ein solcher Block wird als "Globale Erweiterung" bezeichnet und kann auch in Implementierungsdateien vorkommen.
Die interface Global
in der Struktur namespace NodeJS
umschlossen: In unseren Tests greifen wir auf die Funktion mountWithContext
als Mitglied der globalen Variablen mit dem zufälligen Namen global
zu, die von der Node-Umgebung bereitgestellt wird . Diese Variable wird bereits von den Typdeklarationen für Node auf derselben Ebene wie andere globale Umgebungsvariablen wie process
deklariert. Allerdings müssen wir den -Typ erweitern, indem wir ein neues Mitglied hinzufügen. Der Typ dieses globalen global
ist der interface
Global
bereits deklariert innerhalb des namespace
NodeJS
, durch die offiziellen Deklarationen für Node. Wir erreichen dies, indem wir ein neues Mitglied von interface
Global
angeben. Unsere Augmentation muss in die namespace
mit Global
eingeschlossen werden, andernfalls wird sie als separate interface
betrachtet. Grob gesprochen gilt lexikalisches Scoping. (Denken Sie daran, dass TypeScript-Schnittstellen im selben Gültigkeitsbereich mehrfach deklariert werden können und dass diese Deklarationen zusammengeführt werden)
Hinweise
Wo platzieren wir diese Erklärung? Überall dort, wo TypScript es auffängt und in unseren Kompilierungskontext einfügt. Per Konvention werden wir es in eine Datei namens globals.d.ts im Stammverzeichnis unseres Projekts stellen. (Technisch kann es etwas anderes genannt werden und in ein niedrigeres Verzeichnis gehen).
Es ist wichtig zu beachten, dass diese Deklarationsdatei Teil unseres Anwendungscodes ist und in die Quellcodeverwaltung eingecheckt werden sollte.
Es muss nicht neben Drittanbieterdeklarationen in Verzeichnissen wie typings , node_modules / @ types oder
Es ist auch wichtig zu beachten, dass diese Erweiterung nur die TypeScript-Dateien ( .ts
, .tsx
, .d.ts
) betrifft. Wenn wir eher deklarieren, dass diese Funktion vom TypeScript-Sprachdienst übernommen wird, um intellisense bei der Arbeit in .js
oder .jsx,
-Dateien bereitzustellen, funktioniert dieser Ansatz nicht.
Die Funktionssignatur ist falsch, Sie müssen zuerst die generischen Typen deklarieren, zum Beispiel:
%Vor%In Ihrem Fall sollte so etwas funktionieren:
%Vor% Wenn Sie zufällig wissen, um was es bei P
und S
geht, können Sie genauer sein, indem Sie beispielsweise <P extends React.Component, K>
verwenden.
Tags und Links typescript reactjs jestjs typescript-typings enzyme