Come si imposta in modo esplicito una nuova proprietà su `finestra 'a macchina?

voti
247

I ha installato namespace globali per i miei oggetti impostando in modo esplicito una proprietà su window.

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

Dattiloscritto sottolinea MyNamespacee si lamenta che:

La proprietà 'MyNamespace' non esiste sul valore di tipo 'finestra' alcun

Posso fare il codice di lavoro dichiarando MyNamespacecome una variabile ambiente e far cadere l' windowesplicitazione, ma non voglio farlo.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Come posso tenere windowin là e fare dattiloscritto felice?

Come nota a margine trovo particolarmente divertente che dattiloscritto si lamenta perché mi dice che windowè di tipo any, che da sicuramente può contenere qualsiasi cosa.

È pubblicato 03/10/2012 alle 14:01
fonte dall'utente
In altre lingue...                            


19 risposte

voti
253

Per mantenerlo dinamica, basta usare:

(<any>window).MyNamespace
Risposto il 09/06/2015 a 19:18
fonte dall'utente

voti
235

Appena trovato la risposta a questa in risposta di un'altra domanda StackOverflow .

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

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

Fondamentalmente è necessario estendere l'attuale windowinterfaccia per dire di lui circa la nuova proprietà.

Risposto il 03/10/2012 a 14:46
fonte dall'utente

voti
127

O...

si può semplicemente digitare:

window['MyNamespace']

e non otterrete un errore di compilazione e funziona lo stesso di battitura window.MyNamespace

Risposto il 20/11/2012 a 20:36
fonte dall'utente

voti
84

Utilizzando TSX? Nessuna delle altre risposte stavano lavorando per me.

Ecco quello che ho fatto:

(window as any).MyNamespace
Risposto il 15/08/2016 a 23:25
fonte dall'utente

voti
46

La risposta accettato è quello che ho usato per usare, ma con dattiloscritto 0.9. * Non funziona più. La nuova definizione della Windowinterfaccia sembra sostituire completamente la definizione built-in, invece di aumentare esso.

Ho preso a fare questo, invece:

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

declare var window: MyWindow;

UPDATE: Con dattiloscritto 0.9.5 la risposta accettata è lavorare di nuovo.

Risposto il 27/08/2013 a 22:22
fonte dall'utente

voti
29

Se è necessario estendere l' windowoggetto con un tipo personalizzato che richiede l'utilizzo di importè possibile utilizzare il seguente metodo:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

Vedere 'Global Augmentation' nella sezione 'Dichiarazione partecipanti alla concentrazione del Manuale: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

Risposto il 23/10/2016 a 15:24
fonte dall'utente

voti
19

Globali sono "male" :), penso che il modo migliore per avere anche la portabilità è:

In primo luogo si esporta l'interfaccia: (es: ./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

In secondo luogo si importa

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

Terzo gettato finestra var globale con CustomWindow

declare let window: CustomWindow;

In questo modo non si dispone di linea anche rosso in diversi IDE se si utilizza con gli attributi esistenti di oggetto window, così, alla prova finale:

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

Testato con 2.4.x tipografico

Risposto il 27/07/2017 a 13:28
fonte dall'utente

voti
8

Ecco come farlo, se si sta utilizzando dattiloscritto Gestione definizioni !

npm install typings --global

Crea typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Installare il battitura personalizzato:

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

Fatto, usarlo ! Dattiloscritto non si lamenterà più:

window.MyNamespace = window.MyNamespace || {};
Risposto il 19/11/2016 a 21:31
fonte dall'utente

voti
7

Non ho bisogno di fare questo, molto spesso, l'unico caso che ho avuto è stato quando si utilizza Redux Devtools con middleware.

Ho semplicemente fatto:

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

Oppure si potrebbe fare:

let myWindow = window as any;

e poi myWindow.myProp = 'my value';

Risposto il 06/06/2018 a 13:13
fonte dall'utente

voti
5

La maggior parte delle altre risposte non sono perfetti.

  • Alcuni di loro solo sopprimere l'inferenza di tipo per il negozio.
  • Alcuni degli altri si preoccupa solo di variabile globale come spazio dei nomi, ma non come interfaccia / classe

Ho anche incontrato il problema simile questa mattina. Ho provato tante "soluzioni" su SO, ma nessuno di loro non producono alcun tipo di errore assoluto e ad attivare innescando tipo salto in IDE (WebStorm o vscode).

Infine, da qui

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

, Trovo una soluzione ragionevole per collegare tipizzazioni per la variabile globale che funge da interfaccia / classe e namespace entrambi .

Esempio è qui sotto:

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

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Ora, il codice sopra unisce le tipizzazioni di namespace MyNamespacee l'interfaccia MyNamespacenella variabile globale myNamespace(di proprietà della finestra).

Risposto il 19/05/2017 a 03:26
fonte dall'utente

voti
5

Se si utilizza l' angolare CLI è davvero semplice (testato su CLI rc.0):

src / polyfills.ts

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

my-custom-utils.ts

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

Sto utilizzando IntelliJ, così ho anche bisogno di cambiare l'impostazione seguente nell'IDE davanti ai miei nuovi polyfills raccolto:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
Risposto il 21/03/2017 a 13:38
fonte dall'utente

voti
2

Per coloro che vogliono impostare una proprietà calcolata o dinamico sul windowoggetto, ci si accorge che non è possibile con il declare globalmetodo. Per chiarire per questo caso d'uso

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

Si potrebbe tentare di fare qualcosa di simile

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

Quanto sopra sarà errore però. Questo perché in tipografico, le interfacce non giocare bene con le proprietà calcolate e getterà un errore come

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

Per aggirare il problema, si può andare con il suggerire di fusione windowper <any>così si può fare

(window as any)[DynamicObject.key]
Risposto il 13/02/2019 a 00:15
fonte dall'utente

voti
2

Fare un interfaccia personalizzata estende la finestra e aggiungere la vostra proprietà personalizzata come optional.

Poi, lasciare che il customWindow che utilizzano l'interfaccia personalizzata, ma valutate con la finestra originale.

Ha funzionato con il typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 
Risposto il 12/11/2018 a 07:29
fonte dall'utente

voti
2

Ho voluto utilizzare questo in un (6) biblioteca angolare oggi e mi c'è voluto un po 'per farlo funzionare come previsto.

Affinché la mia libreria di utilizzare le dichiarazioni ho dovuto usare l' d.tsestensione del file che dichiara le nuove proprietà dell'oggetto globale.

Così, alla fine, il file si è conclusa con qualcosa di simile:

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

Una volta creato, non dimenticare di esporre nel vostro public_api.ts.

Che ha fatto per me. Spero che questo ti aiuti.

Risposto il 01/08/2018 a 11:29
fonte dall'utente

voti
2

Per avere un riferimento (questa è la risposta corretta):

All'interno di un .d.tsfile di definizione

type MyGlobalFunctionType = (name: string) => void

Se si lavora nel browser, è possibile aggiungere membri al contestuale della finestra del browser riaprendo l'interfaccia di Windows:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

Stessa idea per NodeJS:

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

Ora si dichiara la variabile principale (che in realtà vivono sulla finestra o globale)

declare const myGlobalFunction: MyGlobalFunctionType;

Poi, in un normale .tsfile, ma importato come effetto collaterale, è in realtà implementare esso:

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

E infine usarlo in altre parti del codice di base, sia con:

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

myGlobalFunction("Kevin");
Risposto il 20/04/2017 a 15:50
fonte dall'utente

voti
1

Se si utilizza tipografico 3.x, si può essere in grado di omettere la declare globalparte nelle altre risposte e invece basta usare:

interface Window {
  someValue: string
  another: boolean
}

Questo ha lavorato con me durante l'uso tipografico 3.3, WebPack e TSLint.

Risposto il 12/02/2019 a 21:50
fonte dall'utente

voti
0

TYPESCRIPT non esegue TYPECHECK sulle proprietà di stringa.

window["newProperty"] = customObj;

Idealmente, lo scenario variabile globale dovrebbe evitare. Io lo uso a volte per eseguire il debug di un oggetto nella console del browser.

Risposto il 18/06/2019 a 22:01
fonte dall'utente

voti
0

In primo luogo è necessario dichiarare l'oggetto window in ambito corrente.
Perché dattiloscritto vorrebbe sapere il tipo di oggetto.
Dal momento che oggetto finestra è definita da qualche altra parte non si può ridefinirlo.
Ma è possibile dichiarare come segue: -

declare var window: any;

Questo non ridefinire l'oggetto finestra o non creerà un'altra variabile con nome window.
Questo significa che la finestra viene definita da qualche altra parte e si sta solo riferendo in ambito corrente.

Quindi è possibile fare riferimento al vostro oggetto MyNamespace semplicemente: -

window.MyNamespace

E ora il dattiloscritto non si lamenterà.

Risposto il 01/06/2019 a 01:41
fonte dall'utente

voti
-1

Dopo aver trovato le risposte in giro, credo che questa pagina potrebbe essere utile. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Non sono sicuro circa la storia della dichiarazione di fusione, ma spiega il motivo per cui la seguente potrebbe funzionare.

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

window.MyNamespace = window.MyNamespace || {};
Risposto il 16/03/2017 a 17:38
fonte dall'utente

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