Reputation: 17364
TL;DR Object.getPrototypeOf(e.target)
returns HTMLInputElement
but the compiler says that the type is EventTarget
Long: I have a simple input
<input
className="FilterInput"
type="text"
placeholder="Search for names..."
onKeyUp={filter}
/>
and a function to manage the filter
const filter = (e: React.KeyboardEvent<HTMLInputElement>) => {
console.log(Object.getPrototypeOf(e.target)) // prints "HTMLInputElement"
console.log((e.target as HTMLInputElement).value);
// ... other code
}
I'm trying to understand better the theory that is behind the type management of Typescript, however I don't understand why I have to typehint
(e.target as HTMLInputElement).value
in the second console.log
.
If I don't do it, the compiler (compile time) says Property 'value' does not exist on type 'EventTarget'.
. So this means that at compile time the type of e.target
is EventTarget.
However, at runtime tested with Object.getPrototypeOf(e.target)
, the type is HTMLInputElement
(which has the value
property).
Why is this happening? Is it an error in my code, something related to React or some part of the theory of the type management in Typescript that I'm missing?
Moreover, shouldn't the indication of the generic type in the parameter declaration (e: React.KeyboardEvent<HTMLInputElement>) be enough?
Thanks
Upvotes: 3
Views: 350
Reputation: 1717
The answer to this is actually more related to JS and DOM api's then it is to Typescript.
In short, what you really want is event.currentTarget
, as it will be the actual element to which you attached the listener.
event.target
can be any child element of your element. As it can be any element - it can't be typed safety, so it's typed as the lowest common denominator which is EventTarget
. (but I will say I'm not sure why it's EventTarget and not Element
)
For more information see this answer: What is the exact difference between currentTarget property and target property in JavaScript
Upvotes: 5