TypeScript Version: 2.7.0-dev.201xxxxx
Code
npm install typescript jsdom @types/jsdom
// example.ts
import { JSDOM } from 'jsdom';
let dom = new JSDOM(`
<!DOCTYPE html>
<html>
<head>
<title>Test DOM</title>
</head>
<body>
<input type="button" id="button" />
</body>
</html>
`);
let window = dom.window;
let elem = window.document.getElementById('button');
elem.onclick = (ev: MouseEvent) => {
console.log(`Button clicked, typeArg: ${ev.type}`);
}
let event: MouseEvent = new window.MouseEvent('someTypeArg');
elem.onclick(event);
Expected behavior:
TypeScript compiles, running node example.js outputs the following to console, then exits:
Button clicked, typeArg: someTypeArg
Actual behavior:
TypeScript fails to compile with the following error:
example.ts(19,36): error TS2339: Property 'MouseEvent' does not exist on type DOMWindow
@types/jsdom defines the DOMWindow interface as:
export interface DOMWindow extends Window { eval(script: string): void; }
The Window interface it extends is the one defined by TypeScript. That interface is missing definitions for the Event types, although these Event types are declared outside the Window interface. In web browsers, the Event types exist both globally and on the window object. TypeScript currently handles the former but not the latter.
jsdom does in fact implement the Event types on the dom.window object. You can modify the code above to compile and behave as expected by extending the DOMWindow interface, adding the MouseEvent type to it, and casting the dom.window object to this newly defined interface:
import { JSDOM, DOMWindow } from 'jsdom';
interface WindowWithMouseEvent extends DOMWindow {
MouseEvent: {
prototype: MouseEvent;
new(typeArg: string, eventInitDict?: MouseEventInit): MouseEvent;
}
}
let dom = new JSDOM(`
<!DOCTYPE html>
<html>
<head>
<title>Test DOM</title>
</head>
<body>
<input type="button" id="button" />
</body>
</html>
`);
let window = dom.window as WindowWithMouseEvent;
let elem = window.document.getElementById('button');
elem.onclick = (ev: MouseEvent) => {
console.log(`Button clicked, typeArg: ${ev.type}`);
}
let event: MouseEvent = new window.MouseEvent('someTypeArg');
elem.onclick(event);
I've spoken to the maintainer of @types/jsdom (see this issue) and they suggested raising an issue with your team instead. I agree, seeing as Event types exist on the window object in web browsers.
TypeScript Version: 2.7.0-dev.201xxxxx
Code
Expected behavior:
TypeScript compiles, running
node example.jsoutputs the following to console, then exits:Actual behavior:
TypeScript fails to compile with the following error:
@types/jsdom defines the
DOMWindowinterface as:The
Windowinterface it extends is the one defined by TypeScript. That interface is missing definitions for the Event types, although these Event types are declared outside theWindowinterface. In web browsers, the Event types exist both globally and on thewindowobject. TypeScript currently handles the former but not the latter.jsdom does in fact implement the Event types on the
dom.windowobject. You can modify the code above to compile and behave as expected by extending theDOMWindowinterface, adding theMouseEventtype to it, and casting thedom.windowobject to this newly defined interface:I've spoken to the maintainer of @types/jsdom (see this issue) and they suggested raising an issue with your team instead. I agree, seeing as Event types exist on the
windowobject in web browsers.