Wie stellen Sie explizit eine neue Eigenschaft auf `window` in Typoskript?

stimmen
247

Ich Setup globalen Namensraum für meine Objekte explizit auf eine Eigenschaft festlegen window.

window.MyNamespace = window.MyNamespace || {};

Typoskript unterstreicht MyNamespaceund beschwert sich, dass:

Die Eigenschaft ‚MyNamespace‘ existiert nicht auf Wert vom Typ ‚Fenster‘ any“

Ich kann den Code Arbeit machen , indem er erklärt , MyNamespacewie eine Umgebungsvariable und die Drop windowExplizit aber ich möchte nicht , dass zu tun.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Wie kann ich windowes in und machen Typoskript glücklich?

Als Randnotiz finde ich es besonders komisch , dass Typoskript beschwert , da es mir sagt , dass windowder Typ ist any, der durch jeden Fall alles enthalten kann.

Veröffentlicht am 03/10/2012 um 14:01
quelle vom benutzer
In anderen Sprachen...                            


19 antworten

stimmen
253

Um es dynamisch, benutzen Sie einfach:

(<any>window).MyNamespace
Beantwortet am 09/06/2015 um 19:18
quelle vom benutzer

stimmen
235

Habe gerade die Antwort auf diese in einer anderen Antwort der Frage Stackoverflow .

declare global {
    interface Window { MyNamespace: any; }
}

window.MyNamespace = window.MyNamespace || {};

Grundsätzlich müssen Sie die bestehenden erweitern windowSchnittstelle es über Ihre neue Immobilie zu erzählen.

Beantwortet am 03/10/2012 um 14:46
quelle vom benutzer

stimmen
127

Oder...

Sie können einfach eingeben:

window['MyNamespace']

und Sie werden nicht einen Compiler-Fehler erhalten und es funktioniert genauso wie die Eingabe window.MyNamespace

Beantwortet am 20/11/2012 um 20:36
quelle vom benutzer

stimmen
84

Mit TSX? Keiner der anderen Antworten wurden für mich zu arbeiten.

Hier ist, was ich getan habe:

(window as any).MyNamespace
Beantwortet am 15/08/2016 um 23:25
quelle vom benutzer

stimmen
46

Die akzeptierte Antwort ist , was ich früher, aber mit Typoskript 0.9. * Es nicht mehr funktioniert. Die neue Definition der WindowSchnittstelle scheint vollständig die Einbau-Definition zu ersetzen, anstatt es zu vermehren.

Ich habe zu tun dies stattdessen genommen:

interface MyWindow extends Window {
    myFunction(): void;
}

declare var window: MyWindow;

UPDATE: Mit Typoskript 0.9.5 die akzeptierte Antwort funktioniert wieder.

Beantwortet am 27/08/2013 um 22:22
quelle vom benutzer

stimmen
29

Wenn Sie die verlängern windowObjekt mit einem benutzerdefinierten Typ, der die Verwendung erfordert importSie können die folgende Methode verwenden:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

Siehe ‚Globale Augmentation‘ in der ‚Erklärung Merging‘ Abschnitt des Handbuchs: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

Beantwortet am 23/10/2016 um 15:24
quelle vom benutzer

stimmen
19

Globale sind „böse“ :), ich denke, die beste Art und Weise auch die Portabilität zu haben ist:

Zuerst exportieren Sie die Schnittstelle: (zB: ./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

Zweitens Sie importieren

import {CustomWindow} from './custom.window.ts';

Drittens werfen global var Fenster mit CustomWindow

declare let window: CustomWindow;

Auf diese Weise müssen Sie nicht auch rote Linie in verschiedenen IDE, wenn Sie mit vorhandenen Attributen von Fenster-Objekt verwenden, so dass am Ende try:

window.customAttribute = 'works';
window.location.href = '/works';

Getestet mit Typoskript 2.4.x

Beantwortet am 27/07/2017 um 13:28
quelle vom benutzer

stimmen
8

Hier ist , wie es zu tun, wenn Sie mit Typoskript Definitions - Manager !

npm install typings --global

erstellen typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Installieren Sie Ihre individuelle Typisierung:

typings install file:typings/custom/window.d.ts --save --global

Fertig, verwenden Sie es ! Typoskript wird nicht mehr beschweren:

window.MyNamespace = window.MyNamespace || {};
Beantwortet am 19/11/2016 um 21:31
quelle vom benutzer

stimmen
7

Ich brauche das nicht sehr oft zu tun, den einzigen Fall war ich gehabt habe, als mit Middleware Redux Devtools verwenden.

Ich einfach tat:

const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

Oder Sie tun können:

let myWindow = window as any;

und dann myWindow.myProp = 'my value';

Beantwortet am 06/06/2018 um 13:13
quelle vom benutzer

stimmen
5

Die meisten der anderen Antworten sind nicht perfekt.

  • Einige von ihnen unterdrücken nur die Typinferenz für Shop.
  • Einige der anderen kümmert sich nur um globale Variable als Namespace, aber nicht als Schnittstelle / Klasse

Ich begegne auch das ähnliche Problem an diesem Morgen. Ich habe versucht, so viele „Lösungen“ auf SO, aber keiner von ihnen keine Art Fehler produzieren absolut und ermöglichen Typ Springen in IDE (WebStorm oder vscode) ausgelöst wird.

Schließlich von hier

https://github.com/Microsoft/TypeScript/issues/3180#issuecomment-102523512

Finde ich eine vernünftige Lösung zu Typisierungen für globale Variable anhängen , die sowohl als Schnittstelle / Klasse und Namespace handelt .

Beispiel ist unten:

// typings.d.ts
declare interface Window {
    myNamespace?: MyNamespace & typeof MyNamespace
}

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Nun geht der Code über die Typisierungen von Namespace MyNamespaceund Schnittstelle MyNamespacein der globalen Variablen myNamespace(die Eigenschaft des Fensters).

Beantwortet am 19/05/2017 um 03:26
quelle vom benutzer

stimmen
5

Wenn Sie die verwenden Angular CLI ist es wirklich einfach (auf CLI RC.0 getestet):

src / polyfills.ts

declare global {
  interface Window {
    myCustomFn: () => void;
  }
}

my-custom-utils.ts

window.myCustomFn = function () {
  ...
};

Ich benutze IntelliJ, so dass ich auch die folgende Einstellung in der IDE benötigt ändern, bevor mein neues polyfills abgeholt:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
Beantwortet am 21/03/2017 um 13:38
quelle vom benutzer

stimmen
2

Für diejenigen , die eine berechnete oder dynamische Eigenschaft auf dem festlegen mögen windowObjekt, werden Sie feststellen , dass nicht möglich , mit dem declare globalVerfahren. Um zu klären , für diesen Anwendungsfall

window[DynamicObject.key] // Element implicitly has an 'any' type because type Window has no index signature

Sie könnten versuchen, so etwas zu tun

declare global {
  interface Window {
    [DyanmicObject.key]: string; // error RIP
  }
}

Die oben wird jedoch Fehler. Dies liegt daran, in Typoskript, Schnittstellen spielen nicht gut mit berechneten Eigenschaften und wird wie ein Fehler aus

A computed property name in an interface must directly refer to a built-in symbol

Um dies zu umgehen, können Sie mit dem vorschlagen gehen Gießen windowzu <any>so können Sie tun

(window as any)[DynamicObject.key]
Beantwortet am 13/02/2019 um 00:15
quelle vom benutzer

stimmen
2

Erstellen Sie eine benutzerdefinierte Schnittstelle, um die Fenster und fügen Sie Ihre benutzerdefinierte Eigenschaft als optional erweitert.

Dann lassen Sie die customWindow, die die benutzerdefinierte Schnittstelle verwenden, aber mit dem ursprünglichen Fenster bewertet.

Es ist mit dem typescript@3.1.3 gearbeitet.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 
Beantwortet am 12/11/2018 um 07:29
quelle vom benutzer

stimmen
2

Ich wollte heute dieses in einem Winkel (6) Bibliothek benutzen und es dauerte eine Weile, diese Arbeit zu bekommen, wie erwartet.

Damit meine Bibliothek Erklärungen zu verwenden , ich hatte das verwenden d.tsErweiterung für die Datei, die die neuen Eigenschaften des globalen Objekts erklärt.

Also am Ende endete die Datei mit etwas wie:

/path-to-angular-workspace/angular-workspace/projects/angular-library/src/globals.d.ts

Einmal erstellt, vergessen Sie nicht , es in Ihrem aussetzen public_api.ts.

Das hat es für mich. Hoffe das hilft.

Beantwortet am 01/08/2018 um 11:29
quelle vom benutzer

stimmen
2

Als Referenz (dies ist die richtige Antwort):

Innerhalb einer .d.tsDefinitionsdatei

type MyGlobalFunctionType = (name: string) => void

Wenn Sie im Browser arbeiten, fügen Sie Mitglieder in das Fenster Kontext des Browsers durch Fenster Schnittstelle Wiedereröffnung:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

Gleiche Idee für NodeJS:

declare module NodeJS {
  interface Global {
    myGlobalFunction: MyGlobalFunctionType
  }
}

Jetzt erklären Sie das Root-Variable (das tatsächlich auf Fenster oder global lebt)

declare const myGlobalFunction: MyGlobalFunctionType;

Dann in einer regulären .tsDatei, sondern als Nebeneffekt importiert, können Sie es tatsächlich umsetzen:

global/* or window */.myGlobalFunction = function (name: string) {
  console.log("Hey !", name);
};

Und es schließlich in der Codebasis verwendet anderswo, entweder mit:

global/* or window */.myGlobalFunction("Kevin");

myGlobalFunction("Kevin");
Beantwortet am 20/04/2017 um 15:50
quelle vom benutzer

stimmen
1

Wenn Sie Typoskript 3.x verwenden, können Sie in der Lage sein , das wegzulassen declare globalTeil in den anderen Antworten und stattdessen nur verwenden:

interface Window {
  someValue: string
  another: boolean
}

Das funktionierte bei mir, als Typoskript 3.3, WebPack und TSLint verwenden.

Beantwortet am 12/02/2019 um 21:50
quelle vom benutzer

stimmen
0

Typescript nicht ausführen typecheck auf String-Eigenschaften.

window["newProperty"] = customObj;

Idealerweise sollte das globale Variable Szenario vermieden. Ich benutze es manchmal ein Objekt in Browser-Konsole zu debuggen.

Beantwortet am 18/06/2019 um 22:01
quelle vom benutzer

stimmen
0

Zuerst müssen Sie das Fensterobjekt in aktuellem Bereich erklären.
Da Typoskript möchte die Art des Objekts kennen.
Da Fensterobjekt irgendwo anders definiert ist , können Sie es nicht neu definieren.
Aber man kann es erklären , wie folgt: -

declare var window: any;

Dies wird nicht das Fensterobjekt neu zu definieren oder es wird nicht eine andere Variable mit Namen erstellen window.
Das bedeutet , Fenster irgendwo anders definiert ist und Sie verweisen sie nur im aktuellen Bereich.

Dann können Sie Ihre MyNamespace Objekt beziehen einfach durch: -

window.MyNamespace

Und nun wird das Typoskript nicht beklagen.

Beantwortet am 01/06/2019 um 01:41
quelle vom benutzer

stimmen
-1

Nach der Feststellung Antworten um, ich glaube , diese Seite hilfreich sein könnte. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Nicht sicher über die Geschichte der Erklärung Verschmelzung, aber es erklärt , warum die folgenden funktionieren könnte.

declare global {
    interface Window { MyNamespace: any; }
}

window.MyNamespace = window.MyNamespace || {};
Beantwortet am 16/03/2017 um 17:38
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more