Ich richte globale Namespaces für meine Objekte ein, indem ich explizit eine Eigenschaft auf setze window
.
window.MyNamespace = window.MyNamespace || {};
TypeScript unterstreicht MyNamespace
und beschwert sich über:
Die Eigenschaft 'MyNamespace' ist für den Wert vom Typ 'window' any "nicht vorhanden.
Ich kann den Code MyNamespace
zum Laufen bringen, indem window
ich ihn als Umgebungsvariable deklariere und die explizite Aussage lösche, aber das möchte ich nicht.
declare var MyNamespace: any;
MyNamespace = MyNamespace || {};
Wie kann ich dort bleiben window
und TypeScript glücklich machen?
Als Randnotiz finde ich es besonders lustig, dass sich TypeScript beschwert, da es mir sagt, dass window
es sich um einen Typ handelt, any
der definitiv alles enthalten kann.
typescript
Joshuapoehls
quelle
quelle
Antworten:
Ich habe die Antwort auf diese Frage in der Antwort einer anderen StackOverflow-Frage gefunden .
Grundsätzlich müssen Sie die vorhandene
window
Schnittstelle erweitern, um Informationen zu Ihrer neuen Eigenschaft zu erhalten.quelle
.d.ts
Datei deklariert ist . Es funktioniert nicht, wenn es in einer.ts
Datei verwendet wird, die Importe und Exporte selbst verwendet. Siehe diese Antwort .declare global { interface Window { ... } }
funktioniert mit TypeScript 2.5.2, keine Notwendigkeit für.d.ts
Datei wie oben erwähnterror TS1234: An ambient module declaration is only allowed at the top level in a file.
Als ich es oben in die Datei einfügte, wurde dieser Fehler behoben, sodass Sie dies möglicherweise auch tun müssen.Um es dynamisch zu halten, verwenden Sie einfach:
quelle
as
stattdessen verwenden<>
. Siehe die Antwort von @ david-boyd unten .this
-return (<any> this)['something in scope']
/* tslint:disable */
AB TYPESCRIPT ^ 3.4.3 DIESE LÖSUNG FUNKTIONIERT NICHT MEHR
Oder...
Sie können einfach Folgendes eingeben:
und Sie erhalten keinen Kompilierungsfehler und es funktioniert genauso wie beim Tippen
window.MyNamespace
quelle
window['MyNamespace']()
(nur Klammern hinzufügen)Verwenden Sie TSX? Keine der anderen Antworten funktionierte für mich.
Folgendes habe ich getan:
quelle
(<any> window).MyNamespace
eigentlich<any>
als JSX interpretiert wird, nicht als Typumwandlung.Die akzeptierte Antwort ist die, die ich früher verwendet habe, aber mit TypeScript 0.9. * Funktioniert sie nicht mehr. Die neue Definition der
Window
Schnittstelle scheint die integrierte Definition vollständig zu ersetzen, anstatt sie zu erweitern.Ich habe mich stattdessen dazu entschlossen:
UPDATE: Mit TypeScript 0.9.5 funktioniert die akzeptierte Antwort wieder.
quelle
export default class MyClass{ foo(){ ... } ... }
interface MyWindow extends Window{ mc: MyClass }
declare var window: MyWindow
window.mc = new MyClass()
Dann können Sie foo () zB von der Chrome Dev Tools-Konsole aus wiemc.foo()
declare var...
jede Datei aufrufen, die Sie benötigen.Window
einfach die Tatsache außer Kraft setzen , dass es sich nicht um ein Vanillefenster handelt. Nur die Typprüfung zu umgehen oder zu versuchen, TS zu täuschen, ist auch nicht der richtige Weg.Global sind "böse" :), ich denke, der beste Weg, um auch die Portabilität zu haben, ist:
Zuerst exportieren Sie die Schnittstelle: (zB: ./custom.window.ts)
Zweitens importieren Sie
Drittes globales Var-Fenster mit CustomWindow
Auf diese Weise haben Sie auch keine rote Linie in einer anderen IDE, wenn Sie mit vorhandenen Attributen des Fensterobjekts verwenden. Versuchen Sie also am Ende:
Getestet mit Typescript 2.4.x und neuestem!
quelle
Wenn Sie das
window
Objekt mit einem benutzerdefinierten Typ erweitern müssen, für den die Verwendung erforderlich istimport
, können Sie die folgende Methode verwenden:window.d.ts
Siehe 'Globale Erweiterung' im Abschnitt 'Zusammenführen von Erklärungen' des Handbuchs: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation
quelle
Für diejenigen, die die Angular CLI verwenden , ist dies unkompliziert:
src / polyfills.ts
my-custom-utils.ts
Wenn Sie IntelliJ verwenden, müssen Sie außerdem die folgende Einstellung in der IDE ändern, bevor Ihre neuen Polyfills aufgenommen werden:
quelle
declare global
ist der Trick, und diese Antwort ist nicht wirklich spezifisch für Angular CLI ...Ich muss das nicht sehr oft tun. Der einzige Fall, den ich hatte, war die Verwendung von Redux Devtools mit Middleware.
Ich habe einfach getan:
Oder Sie könnten tun:
let myWindow = window as any;
und dann
myWindow.myProp = 'my value';
quelle
Die meisten anderen Antworten sind nicht perfekt.
Ich stoße heute Morgen auch auf ein ähnliches Problem. Ich habe so viele "Lösungen" auf SO ausprobiert, aber keine von ihnen erzeugt absolut keinen Typfehler und ermöglicht das Auslösen des Typenspringens in der IDE (Webstorm oder Vscode).
Endlich von hier
Ich finde eine vernünftige Lösung, um Typisierungen für globale Variablen anzuhängen, die sowohl als Schnittstelle / Klasse als auch als Namespace fungieren .
Beispiel ist unten:
Der obige Code führt nun die Typisierungen von Namespace
MyNamespace
und SchnittstelleMyNamespace
in die globale VariablemyNamespace
(die Eigenschaft von window) ein.quelle
Nachdem ich Antworten gefunden habe, denke ich, dass diese Seite hilfreich sein könnte. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Sie sind sich nicht sicher über den Verlauf der Zusammenführung von Deklarationen, erklären jedoch, warum das Folgende funktionieren könnte.
quelle
So geht's, wenn Sie TypeScript Definition Manager verwenden !
Erstellen
typings/custom/window.d.ts
:Installieren Sie Ihre benutzerdefinierte Eingabe:
Fertig, benutze es ! Typoskript wird sich nicht mehr beschweren:
quelle
typings
wurde mit Typescript 2.0 (Mitte 2016) überholt und vom Eigentümer archiviert.Typscript führt keine Typprüfung für Zeichenfolgeneigenschaften durch.
Idealerweise sollte das globale Variablenszenario vermieden werden. Ich benutze es manchmal, um ein Objekt in der Browserkonsole zu debuggen.
quelle
Erstellen Sie eine Datei mit dem Namen
global.d.ts
zB/src/@types/global.d.ts
und definieren Sie dann eine Schnittstelle wie:Ref: https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-d-ts.html
quelle
Wenn Sie Typescript 3.x verwenden, können Sie möglicherweise den
declare global
Teil in den anderen Antworten weglassen und stattdessen einfach Folgendes verwenden:Dies funktionierte bei mir bei Verwendung von Typescript 3.3, WebPack und TSLint.
quelle
^3.4.3
. Diese Antwort funktionierte für mich stackoverflow.com/a/42841166/1114926Als Referenz (dies ist die richtige Antwort):
In einer
.d.ts
DefinitionsdateiWenn Sie im Browser arbeiten, fügen Sie dem Fensterkontext des Browsers Mitglieder hinzu, indem Sie die Fensteroberfläche erneut öffnen:
Gleiche Idee für NodeJS:
Jetzt deklarieren Sie die Stammvariable (die tatsächlich im Fenster oder global lebt).
Dann in einem regelmäßigen
.ts
implementieren Sie es Datei, die jedoch als Nebeneffekt importiert wurde, tatsächlich:Und schließlich verwenden Sie es an anderer Stelle in der Codebasis, entweder mit:
quelle
Eine benutzerdefinierte Schnittstelle erstellen erweitert das Fenster und fügt Ihre benutzerdefinierte Eigenschaft optional hinzu.
Lassen Sie dann das customWindow, das die benutzerdefinierte Oberfläche verwendet, aber mit dem ursprünglichen Fenster bewertet.
Es hat mit dem [email protected] gearbeitet.
quelle
Für diejenigen, die eine berechnete oder dynamische Eigenschaft für das
window
Objekt festlegen möchten, ist dies mit derdeclare global
Methode nicht möglich . Zur Verdeutlichung für diesen AnwendungsfallSie könnten versuchen, so etwas zu tun
Das obige wird jedoch fehlerhaft sein. Dies liegt daran, dass in Typescript Schnittstellen mit berechneten Eigenschaften nicht gut funktionieren und einen Fehler wie auslösen
Um dies zu umgehen, können Sie dem Vorschlag des Castings folgen
window
,<any>
damit Sie dies tun könnenquelle
Mit create-react-app v3.3 fand ich den einfachsten Weg, dies zu erreichen, den
Window
Typ in der automatisch generierten zu erweiternreact-app-env.d.ts
:quelle
Zuerst müssen Sie das Fensterobjekt im aktuellen Bereich deklarieren.
Weil Typoskript den Typ des Objekts wissen möchte.
Da das Fensterobjekt an einer anderen Stelle definiert ist, können Sie es nicht neu definieren.
Sie können dies jedoch wie folgt deklarieren:
Dadurch wird das Fensterobjekt nicht neu definiert oder es wird keine weitere Variable mit Namen erstellt
window
.Dies bedeutet, dass das Fenster an einer anderen Stelle definiert ist und Sie es nur im aktuellen Bereich referenzieren.
Dann können Sie einfach auf Ihr MyNamespace-Objekt verweisen, indem Sie:
Oder Sie können die neue Eigenschaft für das
window
Objekt einfach festlegen, indem Sie:Und jetzt wird sich das Typoskript nicht beschweren.
quelle
window
definiert ist?Ich wollte dies heute in einer Angular (6) -Bibliothek verwenden, und es dauerte eine Weile, bis dies wie erwartet funktioniert.
Damit meine Bibliothek Deklarationen verwenden konnte, musste ich die
d.ts
Erweiterung für die Datei verwenden, die die neuen Eigenschaften des globalen Objekts deklariert.Am Ende hatte die Datei also Folgendes:
/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts
Vergessen Sie nach dem Erstellen nicht, es in Ihrem zu belichten
public_api.ts
.Das hat es für mich getan. Hoffe das hilft.
quelle