Skip to content

Event types do not exist in the Window interface #19758

Closed
@KevinSnyderCodes

Description

@KevinSnyderCodes

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions