Как предотвратить "Свойство..." не существует в типе "Глобальный" с jsdom и typescript?

Я пытаюсь преобразовать существующий проект в использование Typescript, и у меня возникают проблемы с настройкой тестирования.

У меня был установочный файл для моих тестов, который устанавливает jsdom, чтобы весь мой код взаимодействия с DOM работал во время моих тестов. Используя Typescript (ts- node с моккой), я всегда получаю такие ошибки:

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

Чтобы предотвратить это, я попробовал исправление интерфейса NodeJS.Global следующим образом:

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

Но это ничего не изменило.

Как включить эти свойства браузера в глобальной переменной NodeJS?

Дополнительно:

Это мой мокко 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/');

Ответ 1

Оригинальный ответ, чтобы избежать ошибки

Поместите это в начало вашего машинописного файла

const globalAny:any = global;

Тогда используйте globalAny.

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

Обновленный ответ для обеспечения безопасности типов

Если вы хотите сохранить безопасность типов, вы можете дополнить существующее определение типа NodeJS.Global.

Вы должны поместить свое определение в глобальную сферу declare global {...}

Имейте в виду, что область видимости global отличается от интерфейса NodeJS Global или узла global property с именем global типа Global...

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

Ответ 2

В дополнение к другим ответам, вы также можете просто привести global непосредственно на сайте назначения:

(global as any).myvar = myvar;

Ответ 3

Я исправил эту проблему, выполнив это...

export interface Global {
  document: Document;
  window: Window;
}

declare var global: Global;

Ответ 4

declare namespace NodeJS {
  export interface Global { window: any;
  }
}

Ответ 5

Избегайте any, он устраняет цель типирования. Вместо этого установите необходимые определения типов (например, yarn add --dev @types/jsdom @types/node) и импортируйте для использования:

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
}