Reputation: 55283
The following code is checking whether the user is in an input, textarea, or contenteditable. If that's the case keys
should be emptied and the code should stop.
let keys: any[] = []
document.addEventListener('keypress', event => {
if (event.key === ' ') return
if (event.target === null) return // Should remove this?
if (event.target.nodeName === 'INPUT' ||
event.target.nodeName === 'TEXTAREA' ||
event.target.isContentEditable) {
keys = []
return
}
})
console.log(keys)
I'm getting this TypeScript error:
Property 'nodeName' does not exist on type 'EventTarget'.
Property 'nodeName' does not exist on type 'EventTarget'.
Property 'isContentEditable' does not exist on type 'EventTarget'.
Why is this and how to fix it?
Live code: https://codesandbox.io/s/cover-image-forked-7n8z7w?file=/src/index.ts
Upvotes: 6
Views: 1802
Reputation: 21926
Event targets can include things like xhr requests and web workers, so Typescript correctly won't let you assume it's a DOM node.
Once you realize that, it just becomes a matter of narrowing the type via runtime checks that are legible to the compiler.
document.addEventListener('keypress', (evt: KeyboardEvent) => {
const { target } = evt;
// Note e.g. XHR requests can be event targets, no nodeName
if (target instanceof HTMLElement) {
console.log(target.nodeName);
if (target.isContentEditable) {
// now we're good to process as e.g. textarea
}
}
});
Upvotes: 6
Reputation: 2444
EventTarget
is not guarantied to be an HTMLElement
or even a Node
You may replace your second condition with
if (!(event.target instanceof HTMLElement)) return;
Upvotes: 13