Skip to content

Use overloads to preserve legacy parameter names when combined with modern Options objects #2470

@spkapust

Description

@spkapust

Context

I'm a member of the TypeScript/JavaScript team at Google. We are currently working on a lint rule that enforces that call-site parameter comments /* likeThis= */ match their declarations.

The problem we are seeing is that several DOM methods have transitioned to using an options bag for certain arguments. In the generated dom.generated.d.ts, these options are collapsed into a single signature using a union type. When this happens, the specific semantic name of the boolean (e.g., useCapture or selfOnly) is replaced by a generic name.

This breaks developer intent for:

IDE Hover Tips: Users see options: boolean | ImportNodeOptions instead of the descriptive boolean name.

Call-site Documentation: Lint rules and internal style guides that enforce parameter comments (e.g., /* selfOnly= */ true) fail because the AST reflects the name options, not selfOnly.


Examples

document.importNode

The spec moved from deep: boolean to an options object where the boolean equivalent (inverted) is now selfOnly.

Current generated type: importNode<T extends Node>(importedNode: T, options?: boolean | ImportNodeOptions): T;

Proposed Overloads:
importNode<T extends Node>(importedNode: T, deep?: boolean): T;
importNode<T extends Node>(importedNode: T, options?: ImportNodeOptions): T;


element.addEventListener

The spec moved from useCapture: boolean to an options object where the boolean equivalent is now capture.

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

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


Some other effected methods include removeEventListener and scrollIntoView


Proposed Solution

I propose that the generator (or manual overrides) split these into explicit overloads to preserve the legacy parameter names alongside the modern object-based signature. I understand these definitions are derived from Web IDL. However, since the TypeScript lib aims to provide the best possible developer experience, adding these overloads to overridingTypes.json (or the equivalent generation logic) would significantly improve the clarity of codebases that still rely on the boolean flags for performance or brevity.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions