[Web API type definition issue] incorrect type definition for `getElementById()`
Summary
incorrect type definition for document.getElementById() and shadowRoot.getElementById()
Expected vs. Actual Behavior
The type definition in lib.dom shows the signature as:
interface Document extends Node, DocumentOrShadowRoot, FontFaceSource, GlobalEventHandlers, NonElementParentNode, ParentNode, XPathEvaluatorBase {
// ... omitted ...
getElementById(elementId: string): HTMLElement | null;
// ... omitted ...
}
The signature should be
interface Document extends Node, DocumentOrShadowRoot, FontFaceSource, GlobalEventHandlers, NonElementParentNode, ParentNode, XPathEvaluatorBase {
// ... omitted ...
getElementById(elementId: string): Element | null;
// ... omitted ...
}
Playground Link
https://www.typescriptlang.org/play/?#code/CYewxgrgtgpgdgFwHQCMTAJ5IJZzjAJwAkAVAWQBkACAXioHIAeAZwDcBzAPkfau2BoAiAGYgQg7gHoujSWy70AUIrAg4zBFV51QkWIlToMAQiTDsBDQFEANjH0IAwgAtsN4KfOWEt+-Ceu7lQAhsxUAMoAagDi0b4OyqrqIHZINiDsABS8uBrBcGAwIMIRMXF2DgCUVJKSVAgEEDBUiWoaWgBMtFS60P5I7DA+Ff4AQhgAksCZ9KIg9NWhpbHx-q3JqelZ7F25CPmFxcvlfojVtVQabjb1jTBAA
Browser Support
- [x] This API is supported in at least two major browser engines (not two Chromium-based browsers).
Have Tried The Latest Releases
- [x] This issue applies to the latest release of TypeScript.
- [x] This issue applies to the latest release of
@types/web.
Additional Context
Proof:
// Run this in your console:
document.body.innerHTML = '<svg><g id="foo"></g></svg>'
const g = document.body!.firstElementChild!.firstElementChild
console.log(g instanceof SVGGElement) // true
const g2 = document.getElementById('foo')
console.log(g2 instanceof SVGGElement) // still true (getElementById did not return HTMLElement | null)
The type is also wrong for other types of documents:
interface DocumentFragment extends Node, NonElementParentNode, ParentNode {
readonly ownerDocument: Document;
getElementById(elementId: string): HTMLElement | null;
}
Can i work on this @saschanaz
This is intentional, as most of the time the desired result would be HTMLElement. We even had complaint when ShadowRoot did return Element instead of HTMLElement. https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1067
By that logic we might as well type event.target as HTMLElement instead of EventTarget which is also totally wrong. I don't think this makes a lot of sense.
I hate the current event.target type but this is far more often used on non html contexts than getElementById or parentElement: window, document, xhr, IDBRequest, MediaQueryList...