Typescript: [typescript] lib.dom.d.ts has confusing types

Created on 21 Apr 2018  ·  5Comments  ·  Source: microsoft/TypeScript

TypeScript Version: 2.8.1
VS Code Version:

Version 1.22.2
Commit 3aeede733d9a3098f7b4bdc1f66b63b0f48c1ef9
Date 2018-04-12T16:38:45.278Z
Shell 1.7.12
Renderer 58.0.3029.110
Node 7.9.0
Architecture x64

Search Terms:
useCapture
addListener
lib.dom.d.ts

Code

const htmlElement: HTMLDivElement;
htmlElement.addEventListener("scroll", event => console.log(event), true);

Before entering the last parameter (just after writing the last comma in the editor):

htmlElement.addEventListener("scroll", event => console.log(event), <----- When the cursor is here

I get code completion that looks like this:

image
And the second overload:
image
It is very confusing to see options?: boolean part not as a separate overload, but as a smushed definition of:

options?: boolean | AddEventListenerOptions | undefined

Expected behavior:
To have separate overloads for boolean version and AddEventListenerOptions one, as seen in CodeSandbox (Playground link).

Actual behavior:
Described above.

Playground Link:
https://codesandbox.io/s/r0l6j9olpn

Related Issues:
Didn't find.

The interesting thing is that while trying to reproduce the issue in CodeSandbox, I got exactly what I wanted to see: useCapture: boolean | undefined
image

So, my question is why does VS Code have a version of types that is confusing and can also be found here:
https://github.com/Microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L5450

And why CodeSandbox has a proper one? And how can we solve this?
Is this VS Code's bug or the lib.dom.d.ts bundled with TypeScript is simply out-of-date?

Awaiting More Feedback lib.d.ts Suggestion

Most helpful comment

I can confirm that useCapture would have helped a lot... Spent quite some time thinking:

What is that options: boolean thing? And how do I set useCapture?

Do you plan updating the lib.dom.d.ts?

All 5 comments

Hmmm.... I see that there already is a related issue: [typescript] dom definitions not up to date https://github.com/Microsoft/TypeScript/issues/19040

The sad thing is that it is not solved since Oct 9, 2017, but CodeSandbox has done something about it already, so there must be a version of lib.dom.d.ts that is newer.
But TypeScript bundles a version that is out of date and we all know that confusing types might be worse than no types 🙂 How can we solve this once and for all?
Maybe including lib.dom.d.ts into DefinitelyTyped community's responsibility would break the ice on this one?
I've contributed to quite a few package types there directly and with colleagues, code and discussions, reviewing PRs and approving or declining them (react being the biggest and most used one) and no matter the size of the types, they evolve to better state over time and are usually up to date. With lib.dom.d.ts, I have no idea how to properly contribute and how can there be better and newer versions out there (CodeSandbox case), when TypeScript's repo one is out of date for years?

The library is generated from https://github.com/Microsoft/TSJS-lib-generator. You can find more information about contributing lib.d.ts fixes at https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md#contributing-libdts-fixes.

So the suggession here is to have two overloads?

interface HTMLDivElement extends HTMLElement {
    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean): void;
    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: AddEventListenerOptions): void;

    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean ): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: AddEventListenerOptions): void;

    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean): void;
    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: EventListenerOptions): void;

    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean): void;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: EventListenerOptions): void;
}

Yes, except boolean parameter should be called useCapture for clarity.

interface HTMLDivElement extends HTMLElement {
    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;
    addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: AddEventListenerOptions): void;

    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean ): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: AddEventListenerOptions): void;

    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, useCapture?: boolean): void;
    removeEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: EventListenerOptions): void;

    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
    removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: EventListenerOptions): void;
}

And there are more occurrences of this parameter type, not only HTMLDivElement.

To be more precise, 393 occurrences of this particular type definition.
image

If you know how to resolve this with https://github.com/Microsoft/TSJS-lib-generator in a quickly, it would be amazing to have this fix throughout all lib.dom.d.ts 🙂

I can confirm that useCapture would have helped a lot... Spent quite some time thinking:

What is that options: boolean thing? And how do I set useCapture?

Do you plan updating the lib.dom.d.ts?

Was this page helpful?
0 / 5 - 0 ratings