-
Couldn't load subscription status.
- Fork 13.1k
Description
🔎 Search Terms
onerror GlobalEventHandlers
🕗 Version & Regression Information
As far as I can tell, this has always been wrong. There are a number of issues (and merged fixes) around onerror and/or addEventListener("error", but all of them have concerned themselves with getting the definition correct for Window.
⏯ Playground Link
💻 Code
declare const htmlElement: HTMLElement;
htmlElement.onerror((event: Event) => {}); // should not error🙁 Actual behavior
The type definitions in lib.dom.d.ts for addEventListener("error" and onerror used by HTMLElement match the spec for Window, which has unique handling of these events for historical reasons.
🙂 Expected behavior
The type definitions in lib.dom.d.ts for addEventListener("error" and onerror event handling on HTMLElement would match the spec for HTMLElement.
Additional information about the issue
In lib.dom.d.ts, we have GlobalEventHandlersEventMap, which is used to define addEventListener, and GlobalEventHandlers, used to define the various on${string} event handler properties. As the name suggests, these are meant to handle “global” events, and Document, Window, HTMLElement, SVGElement, and MathMLElement all inherit these.
Unfortunately, the definitions here for addEventListener("error" and onerror are used uniquely by Window. None of the other types inheriting these definitions are correct for error events.
These are the definitions:
interface GlobalEventHandlersEventMap {
// …
"error": ErrorEvent;
// …
}
interface GlobalEventHandlers {
// …
/**
* Fires when an error occurs during object loading.
* @param ev The event.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLElement/error_event)
*/
onerror: OnErrorEventHandler;
// …
}
// …
type OnErrorEventHandler = OnErrorEventHandlerNonNull | null;
// …
interface OnErrorEventHandlerNonNull {
(event: Event | string, source?: string, lineno?: number, colno?: number, error?: Error): any;
}Note that MDN link for onerror that specifically directs to HTMLElement/error_event: that page says,
Syntax
Use the event name in methods like
addEventListener(), or set an event handler property.addEventListener("error", (event) => { }) onerror = (event) => { }Event type
The event object is a
UIEventinstance if it was generated from a user interface element, or anEventinstance otherwise.
Just a single argument that is either Event or UIEvent. Both the five-argument onerror definition and the single ErrorEvent argument "error" definition are wrong for HTMLElement.
Instead, those definitions are from Window, and are defined correctly for Window, including the discrepancy in the arguments between addEventListener and onerror. Well, the GlobalEventHandlersEventMap definition is possibly less than precise:
The event object is a
ErrorEventinstance if it was generated from a user interface element, or anEventinstance otherwise.
However, the page notes that all of this is unique to Window:
Note: For historical reasons,
onerroronWindowandWorkerGlobalScopeobjects is the only event handler property that receives more than one argument.
The event handler's signature is asymmetric between
addEventListener()andonerror. The event handler passed toWindow.addEventListener()receives a singleErrorEventobject, while theonerrorhandler receives five arguments, matching theErrorEventobject's properties:
This special behavior only happens for the
onerrorevent handler onwindow. TheElement.onerrorhandler still receives a singleErrorEventobject.
(Side note: the “Element.onerror” link in that last quote actually goes to HTMLElement, and according to that page, it’s a UIEvent or Event, not an ErrorEvent, so MDN has some issues here, too.)
Thus, these definitions should only be applied to Window in lib.dom.d.ts, and onerror/addEventListener("error" for HTMLElement, SVGElement, and MathMLElement should be defined differently. (I can’t actually find definitions of onerror for MathMLElement on MDN, nor for Document which I also see using GlobalEventHandlers in lib.dom.d.ts, but I haven’t dug into those cases much.)