What I want (an example of all the events suggested for addEventListener
on the document
object):
What I have (events suggested for addEventListner
on the object returned from my document.querySelector
query (only fullscreenchange
and fullscreenerror
)):
I want suggestions as shown in the first image.
Here's a transcription of the above images so you can try for yourself:
const titleElement = document.querySelector("#title");
document.addEventListener("", (ev) => {});
// ^lots of suggested event names
titleElement.addEventListener("", (ev) => {});
// ^only the `fullscreenchange` and `fullscreenerror` events are suggested
This is due to typing. document.querySelector
is only guaranteed to return an element of type Element
, although, of course, it can return an object of a subtype of Element
. But for the type definitions in lib.dom.ts
, Element
is only defined to have those two events (fullscreenchange
and fullscreenerror
) on them- probably because those are the only two events that are valid for all possible Element
subtypes.
To solve your problem, you can pass the type you expect as a generic argument to the querySelector
call, like this:
document.querySelector<HTMLHeadingElement>("#title")
which will type the returned object as HTMLHeadingElement | null
.
Alternatively, you can add a type assertion to tell the TypeScript compiler or VS Code the exact type you expect that queried element to be.
In TypeScript, you can do a type assertion with the as
keyword like this (you need to add | null
yourself if you want it):
const titleElement = document.querySelector("#title") as HTMLHeadingElement;
// or whatever HTML type your `#title`-IDed element is.
In JavaScript, you can use JSDoc comments to make type hints that VS Code and other tools will recognize:
/** @type {HTMLHeadingElement} */
const titleElement = document.querySelector("#title");
Or, you can wrap your usage of the object returned from the query with a type check:
const titleElement = document.querySelector("#title");
if (titleElement instanceof HTMLHeadingElement) {
titleElement.addEventListever("click", (ev) => {
console.log("hello world!");
});
}
The TypeScript language server that powers IntelliSense in VS Code will know that inside that if-block, the type of titleElement
must be at least HTMLHeadingElement
(or whatever type you specify in the instanceof
check) because of the instanceof
check. You can read more about the instanceof
operator on MDN.
To get a list of all existing HTML elements, one place to look is MDN's HTML Element Reference page, or you can just type HTML
in your file in VS Code and trigger autocomplete suggestions.