In a React app, where I use Typescript and MaterialUI, I have a TextField.
I would like to get access to the input
html element value when enter
is pressed.
So I have the following code
const keyPress = (e: any) => {
if (e.key === "Enter") {
console.log("Do login", e.target.value);
}
};
and somewhere in the returned React tree I have this
<TextField onKeyPress={keyPress} />
This code works, bu my problem is that I do not understand how to define the right type for the event e
passed to the function keyPressed
.
According to what VSCode intellisense is suggesting when I hover over onKeyPress
prop, I understand I should use KeyboardEvent<HTMLDivElement>
, but the problem is that then I get an error which says Type 'KeyboardEvent' is not generic
.
What I am doing wrong?
By the way, everything works fine if I give the event the type e: { key: string; target: any }
, but still it is interesting to understand what I am doing wrong when I try to follow the right way.
UPDATE
After some more research, it seems that the event passed to keyPressed
function is of type KeyboardEvent
and that its target
property is of type EventTarget
.
Looking at the definition of EventTarget
in global.d.ts
in React
package, then I see that it is the empty interface.
In the comments of global.d.ts
I read also that "Warning: all of these interfaces are empty. If you want type definitions for various properties
(such as HTMLInputElement.prototype.value), you need to add --lib DOM
(via command line or tsconfig.json).". But my tsconfig.json
actually contains DOM
in the libraries (the property is "lib": ["dom", "dom.iterable", "esnext"],
).
Again, I can make things work, but I would like to understand how to get a clean type for that event.
You can define typing for onKeyPress
handler i.e. keyPress
as:
import { KeyboardEvent, EventHandler } from 'react'
const keyPress: EventHandler<KeyboardEvent<HTMLInputElement>> = (e) => {
if (e.key === 'Enter') {
console.log('Do login', (e.target as HTMLInputElement).value)
}
}
<TextField id="id" label="Name" onKeyPress={keyPress} />
Typescript will give you below error ...
Property 'value' does not exist on type 'EventTarget'.
Another post on this error: Property 'value' does not exist on type EventTarget in TypeScript
... when you access value - e.target.value
though the value
exists, so you can suppress this error by casting it as HTMLInputElement
as shown above.
In my opinion, you are trying to access e.key
, not the e.target.value
in onKeyPress
handler; as you are most likely to do that in onChange
handler.
Same but, maybe, shorter form:
type KeyPressType<T = Element> = EventHandler<KeyboardEvent<T>>
const keyPress: KeyPressType<HTMLInputElement> = (e) => {
if (e.key === 'Enter') {
console.log('Do login', (e.target as HTMLInputElement).value)
}
}
Question: What's the type of e
?
Answer: It is KeyboardEvent<HTMLInputElement>