Hoe weet u expliciet een nieuwe woning op `window` de schrijfmachine?

stemmen
247

Ik setup wereldwijde namespaces voor mijn objecten door expliciet het instellen van een woning op window.

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

Typoscript onderstreept MyNamespaceen klaagt dat:

Het pand 'MyNamespace' bestaat niet op de waarde van het type 'venster' elke

Ik kan de code te laten werken door te verklaren MyNamespaceals een ambient variabele en het schrappen van de windowexpliciete, maar ik wil niet om dat te doen.

declare var MyNamespace: any;

MyNamespace = MyNamespace || {};

Hoe kan ik windowdaar en maak typoscript gelukkig?

Als een kanttekening vind ik het vooral grappig dat typoscript klaagt omdat het me vertelt dat windowis van het type any, die door zeker kan van alles bevatten.

De vraag is gesteld op 03/10/2012 om 14:01
bron van user
In andere talen...                            


19 antwoorden

stemmen
253

Om het dynamisch te houden, gewoon gebruik maken van:

(<any>window).MyNamespace
antwoordde op 09/06/2015 om 19:18
bron van user

stemmen
235

Net vond het antwoord op deze in antwoord op een andere StackOverflow vraag's .

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

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

In principe moet u het bestaande uit te breiden windowinterface om het te vertellen over uw nieuwe woning.

antwoordde op 03/10/2012 om 14:46
bron van user

stemmen
127

Of...

je kunt gewoon typen:

window['MyNamespace']

en je krijgt gewoon een compileerfout en het werkt hetzelfde als het typen window.MyNamespace

antwoordde op 20/11/2012 om 20:36
bron van user

stemmen
84

Met behulp van TSX? Geen van de andere antwoorden werkten voor mij.

Hier is wat ik deed:

(window as any).MyNamespace
antwoordde op 15/08/2016 om 23:25
bron van user

stemmen
46

De aanvaarde antwoord is wat ik gebruikt om het gebruik, maar met Typescript 0.9. * Het niet meer werkt. De nieuwe definitie van het Windowgrensvlak lijkt volledig vervangen van de ingebouwde definitie, in plaats van het verhogen van het.

Ik heb genomen om dit te doen in plaats daarvan:

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

declare var window: MyWindow;

UPDATE: Met typoscript 0.9.5 de aanvaarde antwoord is weer aan het werk.

antwoordde op 27/08/2013 om 22:22
bron van user

stemmen
29

Als u nodig hebt om het te verlengen windowobject met een aangepaste soort die het gebruik van vereist importkunt u de volgende methode gebruiken:

window.d.ts

import MyInterface from './MyInterface';

declare global {
    interface Window {
        propName: MyInterface
    }
}

Zie 'Global Augmentation' in de 'Verklaring samenvoegen' sectie van het handboek: https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation

antwoordde op 23/10/2016 om 15:24
bron van user

stemmen
19

Global zijn "het kwaad" :), ik denk dat de beste manier om ook de draagbaarheid is:

Eerst exporteert u de interface: (bv: ./custom.window.ts)

export interface CustomWindow extends Window {
    customAttribute: any;
}

Tweede u importeert

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

Derde gegoten wereldwijde var venster met CustomWindow

declare let window: CustomWindow;

Op deze manier hoef je niet ook rode lijn in verschillende IDE als je gebruik maakt van bestaande attributen van het venster object, zodat aan het eind try:

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

Getest met Typescript 2.4.x

antwoordde op 27/07/2017 om 13:28
bron van user

stemmen
8

Hier is hoe het te doen, als je met behulp typoscript Definition Manager !

npm install typings --global

Maak typings/custom/window.d.ts:

interface Window {
  MyNamespace: any;
}

declare var window: Window;

Installeer uw aangepaste typen:

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

Gedaan, gebruik het ! Typescript zal niet meer klagen:

window.MyNamespace = window.MyNamespace || {};
antwoordde op 19/11/2016 om 21:31
bron van user

stemmen
7

Ik hoef niet om dit heel vaak te doen, het enige geval dat ik heb gehad bij het gebruik van Redux DevTools met middleware.

Ik deed gewoon:

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

Of je zou kunnen doen:

let myWindow = window as any;

en dan myWindow.myProp = 'my value';

antwoordde op 06/06/2018 om 13:13
bron van user

stemmen
5

De meeste van de andere antwoorden zijn niet perfect.

  • Sommigen van hen gewoon te onderdrukken het type gevolgtrekking voor de winkel.
  • Sommige van de anderen alleen cares over globale variabele als namespace, maar niet zo-interface / klasse

Ik ontmoet ook de soortgelijk probleem vanmorgen. Ik heb geprobeerd zo veel "oplossingen" op SO, maar geen van hen produceren geen typefout absoluut en in staat triggering soort springen in IDE (WebStorm of vscode).

Tot slot, vanaf hier

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

, Vind ik een redelijke oplossing voor typeringen hechten globale variabele die fungeert als interface / klasse en namespace beide .

Voorbeeld hieronder:

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

declare interface MyNamespace {
    somemethod?()
}

declare namespace MyNamespace {
    // ...
}

Nu, de bovenstaande code voegt de typeringen van namespace MyNamespaceen de interface MyNamespacein de globale variabele myNamespace(de eigenschap van het venster).

antwoordde op 19/05/2017 om 03:26
bron van user

stemmen
5

Als u gebruik maakt van de Angular CLI het is echt eenvoudig (getest op CLI RC.0):

src / polyfills.ts

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

my-maat-utils.ts

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

Ik gebruik IntelliJ, dus ik moest ook de volgende instelling in de IDE wijzigen voordat mijn nieuwe polyfills opgepikt:

> File 
> Settings 
> Languages & Frameworks 
> TypeScript 
> check 'Use TypeScript Service'.
antwoordde op 21/03/2017 om 13:38
bron van user

stemmen
2

Voor degenen die willen een berekende of dynamische woning op de set windowobject, dan heb je dat niet mogelijk is te vinden bij de declare globalmethode. Om duidelijk te maken voor deze use case

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

Je zou kunnen proberen om iets als dit te doen

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

De bovenstaande zal wel fout. Dit komt omdat in Typescript, interfaces niet goed spelen met berekende eigenschappen en zal een foutmelding als gooi

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

Om dit te omzeilen, kun je gaan met de voorstellen van het gieten windowop <any>, zodat u kunt doen

(window as any)[DynamicObject.key]
antwoordde op 13/02/2019 om 00:15
bron van user

stemmen
2

Maak een aangepaste interface breidt het Venster en uw aangepaste eigenschap toevoegen als optionele.

Vervolgens laat de customWindow dat de aangepaste interface te gebruiken, maar gewaardeerd met het oorspronkelijke venster.

Het is samengewerkt met de typescript@3.1.3.

interface ICustomWindow extends Window {
  MyNamespace?: any
}

const customWindow:ICustomWindow = window;

customWindow.MyNamespace = customWindow.MyNamespace {} 
antwoordde op 12/11/2018 om 07:29
bron van user

stemmen
2

Ik wilde deze gebruiken in een Angular (6) bibliotheek vandaag en het kostte me een tijdje om dit te laten werken zoals verwacht.

Om mijn bibliotheek aan declaraties moest ik de gebruiken d.tsextensie voor het bestand dat de nieuwe eigenschappen van de wereldwijde object verklaart.

Dus op het einde, het bestand eindigde met iets als:

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

Eens gemaakt, vergeet dan niet om het te bloot in je public_api.ts.

Dat deed het voor mij. Ik hoop dat dit helpt.

antwoordde op 01/08/2018 om 11:29
bron van user

stemmen
2

Ter referentie (dit is het juiste antwoord):

Binnen een .d.tsdefinitie bestand

type MyGlobalFunctionType = (name: string) => void

Als u werkt in de browser, je leden om venster context van de browser toe te voegen door heropening interface van Window's:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

Hetzelfde idee voor NodeJS:

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

Nu verklaart u de wortel variabele (die ook daadwerkelijk live op raam of mondiaal)

declare const myGlobalFunction: MyGlobalFunctionType;

Dan in een gewone .tsfile, maar als neveneffect geïmporteerd, u daadwerkelijk te implementeren:

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

En ten slotte gebruik het elders in de codebase, met ofwel:

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

myGlobalFunction("Kevin");
antwoordde op 20/04/2017 om 15:50
bron van user

stemmen
1

Als u gebruik maakt Typescript 3.x, kunt u in staat om het weg te laten declare globaldeelnemen aan de andere antwoorden en in plaats daarvan gewoon gebruik maken van:

interface Window {
  someValue: string
  another: boolean
}

Dit werkte bij mij bij het gebruik van Typescript 3.3, WebPack en TSLint.

antwoordde op 12/02/2019 om 21:50
bron van user

stemmen
0

Typscript voert geen typecheck op tekenreekseigenschappen.

window["newProperty"] = customObj;

Idealiter zou de globale variabele scenario vermeden. Ik gebruik het soms om een ​​object in de browser console debuggen.

antwoordde op 18/06/2019 om 22:01
bron van user

stemmen
0

Eerst moet u het venster object te verklaren in de huidige scope.
Omdat typoscript wil de aard van het object te leren kennen.
Sinds window object ergens anders gedefinieerd is kan je niet herdefiniëren.
Maar je kunt het te verklaren als volgt: -

declare var window: any;

Dit zal niet herdefiniëren het venster object of het zal een andere variabele met de naam niet maken window.
Dit betekent dat venster is ergens anders gedefinieerd en je gewoon vermeld wordt in de huidige scope.

Dan kunt u verwijzen naar uw MyNamespace object simpelweg door: -

window.MyNamespace

En nu het typoscript zal niet klagen.

antwoordde op 01/06/2019 om 01:41
bron van user

stemmen
-1

Na het vinden van antwoorden rond, ik denk dat deze pagina kan nuttig zijn. https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-augmentation Ik weet niet zeker over de geschiedenis van de verklaring samenvoegen, maar het verklaart waarom de volgende zou kunnen werken.

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

window.MyNamespace = window.MyNamespace || {};
antwoordde op 16/03/2017 om 17:38
bron van user

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