When I checked the result of typeof event
, it returned as object
.
This is JavaScript runtime code, utilizing the typeof
operator that always returns "object"
for all objects (including null
).
I realized that my code needed some modifications when I encountered an error in VS Code like the one mentioned below.
It's worth noting that plain objects do not contain a target
property.
For a click
event, the type of the event object is MouseEvent
. If you are using jQuery or Angular to attach the event, it will rely on the DOM's MouseEvent
. In this case, using event.currentTarget.id
or event.target.id
is recommended over accessing the attributes
collection and nodeValue
since the id
attribute is a reflected property.
Despite this, the MouseEvent
interface considers both currentTarget
and target
properties as EventTarget
, even though they are essentially referring to an Element
. This deviation prompts the need for a type assertion:
onClick(event: MouseEvent) {
console.log((event.target as Element).id); // Alternatively, you can use `(event.currentTarget as Element).id`
}
Playground link
While type assertions may not be ideal, they are sometimes necessary for such scenarios. There are alternative ways to perform the same assertion, like the examples provided below:
onClick({target}: {target: Element}) {
console.log(target.id);
}
// or
onClick({currentTarget}: {currentTarget: Element}) {
console.log(currentTarget.id);
}
Playground link
You could introduce a reusable type for more clarity:
interface ElementMouseEvent extends MouseEvent {
currentTarget: Element;
target: Element;
}
Utilizing this custom type would still involve making an assertion but ensures safety:
onClick(event: ElementMouseEvent) {
console.log(event.target.id); // Or `event.currentTarget.id`
}
Playground link
If you desire complete type safety, you could implement a type assertion function that throws a clear error if the assertion fails:
function assertIsElement(obj: object | null): asserts obj is Element {
if (!(obj instanceof Element)) {
throw new Error(`Object is not an Element instance`);
}
}
// ...
onClick({currentTarget}: MouseEvent) {
assertIsElement(currentTarget);
console.log(currentTarget.id);
}
Playground link
In cases where you have control over the usage of onClick
and are certain it pertains to an Element
, this level of strictness may be unnecessary.