How to prevent "Property ..." does not exist in the type "Global" with jsdom and typescript?

I am trying to convert an existing project to using Typescript, and I am having problems setting up testing.

I had a setup file for my tests that installs jsdom so that all of my DOM interaction code would work during my tests. Using Typescript (ts-node with a wet), I always get errors like this:

Property 'window' does not exist on type 'Global'. 

To prevent this, I tried fixing the NodeJS.Global interface as follows:

 declare namespace NodeJS{ interface Global { document: Document; window: Window; navigator: Navigator; } } 

But that didnโ€™t change anything.

How to enable these browser properties in a global variable NodeJS?

Additionally:

This is my mocha setup.ts :

 import { jsdom, changeURL } from 'jsdom'; const exposedProperties = ['window', 'navigator', 'document']; global.document = jsdom(''); global.window = global.document.defaultView; Object.keys(global.document.defaultView).forEach((property) => { if (typeof global[property] === 'undefined') { exposedProperties.push(property); global[property] = global.document.defaultView[property]; } }); global.navigator = { userAgent: 'node.js', }; changeURL(global.window, 'http://example.com/'); 
+35
source share
5 answers

Original answer to avoid error

Put this at the top of your typescript file

 const globalAny:any = global; 

Then use globalAny.

 globalAny.document = jsdom(''); globalAny.window = global.document.defaultView; 

Updated answer for type safety

If you want to maintain type safety, you can supplement the existing type definition with NodeJS.Global .

You must put your definition in the global scope declare global {...}

Keep in mind that the global scope is different from the NodeJS Global interface or the global property node named global type Global ...

 declare global { namespace NodeJS { interface Global { document: Document; window: Window; navigator: Navigator; } } } 
+52
source

In addition to the other answers, you can also simply bring global directly to the destination site:

 (global as any).myvar = myvar; 
+20
source

I fixed this problem by doing this ...

 export interface Global { document: Document; window: Window; } declare var global: Global; 
+11
source
 declare namespace NodeJS { export interface Global { window: any; } } 
+3
source

Avoid any , it eliminates the purpose of typing. Instead, install the necessary type definitions (e.g. yarn add --dev @types/jsdom @types/node ) and import to use:

 import { DOMWindow, JSDOM } from 'jsdom' interface Global extends NodeJS.Global { window: DOMWindow, document: Document, navigator: { userAgent: string } } const globalNode: Global = { window: window, document: window.document, navigator: { userAgent: 'node.js', }, ...global } 
+3
source

Source: https://habr.com/ru/post/1012562/


All Articles