Ich versuche, ein vorhandenes Projekt für die Verwendung von Typescript zu konvertieren, und habe Probleme mit meinem Test-Setup.
Ich hatte eine Setup-Datei für meine Tests, die jsdom so einrichtet, dass mein gesamter DOM-Interaktionscode während meiner Tests funktioniert. Mit Typescript (ts-Knoten mit Mokka) erhalte ich immer folgende Fehler:
Property 'window' does not exist on type 'Global'.
Um dies zu verhindern, habe ich versucht, die NodeJS.Global-Oberfläche wie folgt zu patchen:
declare namespace NodeJS{
interface Global {
document: Document;
window: Window;
navigator: Navigator;
}
}
Daran hat sich aber nichts geändert.
Wie aktiviere ich diese Browsereigenschaften für die globale NodeJS-Variable?
Extras:
Das ist mein Mokka 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/');
typescript
jsdom
typescript2.0
fahrradflucht
quelle
quelle
Antworten:
Ursprüngliche Antwort, um Fehler zu vermeiden
Fügen Sie dies oben in Ihre Typoskriptdatei ein
const globalAny:any = global;
Verwenden Sie stattdessen globalAny.
globalAny.document = jsdom(''); globalAny.window = global.document.defaultView;
Aktualisierte Antwort zur Aufrechterhaltung der Typensicherheit
Wenn Sie Ihre Typensicherheit beibehalten möchten, können Sie die vorhandene
NodeJS.Global
Typdefinition erweitern.Sie müssen Ihre Definition in den globalen Bereich einfügen
declare global {...}
global
Beachten Sie, dass der Typoskriptbereich nicht mit der NodeJS-SchnittstelleGlobal
oder dem vom Typglobal property
aufgerufenen Knoten identisch ist ...global
Global
declare global { namespace NodeJS { interface Global { document: Document; window: Window; navigator: Navigator; } } }
quelle
any
wirklich der Frage, warum Typescript überhaupt verwendet wird. Infact, wenn Sie fusseln TSLint hat eine Option speziell, um dies zu verhindern: palantir.github.io/tslint/rules/no-anyNeben anderen Antworten können Sie auch einfach direkt am Einsatzort gießen
global
:(global as any).myvar = myvar;
quelle
Ich habe dieses Problem dadurch behoben ...
export interface Global { document: Document; window: Window; } declare var global: Global;
quelle
export interface Global extends NodeJS.Global
Wenn Sie einige ändern möchten, aber den Rest der Eigenschaften von Globalfetch
Vermeiden
any
Sie Typografie, da dies den Zweck der Typisierung aufhebt. Installieren Sie stattdessen die erforderlichen Typdefinitionen (z. B.yarn add --dev @types/jsdom @types/node
) und importieren Sie sie, um Folgendes zu verwenden: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 }
quelle
Dies ist die richtige Lösung, ohne die Namespaces von Typescript zu verwenden. Es ist auch mit allen Standardregeln von eslint kompatibel:
// Declare a type. interface CustomNodeJsGlobal extends NodeJS.Global { myExtraGlobalVariable: number; // You can declare anything you need. }
Benutze es:
// Tell Typescript to use this type on the globally scoped `global` variable. declare const global: CustomNodeJsGlobal; function doSomething() { // Use it freely global.myExtraGlobalVariable = 5; } doSomething();
quelle
eslint: error @typescript-eslint/no-unsafe-member-access - Unsafe member access .Global on an any value.
möglicherweise angezeigt. Gelöst durchtype NJSGlobal = NodeJS.Global;
vorheriges Hinzufügen und ErweiternNJSGlobal
. Darüber hinaus scheint diese Lösung der beste Weg zu sein.declare namespace NodeJS { export interface Global { window: any; } }
quelle