0
votes

I'm trying to write a properly typed callback function for the onKeyPress event.

I've tried giving either the function or the event various types, but I can't seem to get the event e to be recognized as having both the key field and the target.value field.


Case 1:

 const onKeyPress: React.KeyboardEventHandler = async (e) => {
     if (e.key === "Enter") {
         console.log(e.target.value);
     }
 };

Message:

TS2339: Property 'value' does not exist on type 'EventTarget'.

Case 2:

 const onKeyPress = async (e: React.KeyboardEvent<HTMLInputElement>) => {
     if (e.key === "Enter") {
         console.log(e.target.value);
     }
 };

Message:

TS2339: Property 'value' does not exist on type 'EventTarget'.

Case 3:

Turns out that even writing this simple JSX is going to throw out the same error:

 <input type="text" onKeyPress={(e) => {
     const key = e.key;
     const val = e.target.value;
 }}/>

Environment

From package.json:

"@types/react": "^16.8.3"

"react": "^16.8.2"

"react-dom": "^16.8.2"

TypeScript 3.2.1.

Any clue?

Update

Accepted answer led me to this working piece of code:

 const onKeyPress = async (e: React.KeyboardEvent<HTMLInputElement>) => {
     if (e.key === "Enter") {
         console.log(`Received: ${e.currentTarget.value}`);
         await doAsyncStuff(e.currentTarget.value);
     }
 };
3

3 Answers

3
votes

Typescript is right here, value does not exists on any html element. You need to be more precise about what kind of element it is.

If you replace your event by

React.KeyboardEvent<HTMLInputElement>

it should work.

You also need to use event.currentTarget instead of target.

2
votes

The target property refers to an element the event occurs on, not the element the handler was attached. That's why it only has properties common to all events, and value is not one of them.

In order to access the value property, you need to get it from the currentTarget property.

You can see this behaviour in the React's type definition file.

/**
 * currentTarget - a reference to the element on which the event listener is registered.
 *
 * target - a reference to the element from which the event was originally dispatched.
 * This might be a child element to the element on which the event listener is registered.
 * If you thought this should be `EventTarget & T`, see https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12239
 */
0
votes

Try...

 const onKeyPress = async (e: React.KeyboardEvent<FormControl>) => {
      console.log(e.target.value);
 };

OR

 const onKeyPress = async (e: KeyboardEventHandler<FormControl>) => {
     console.log(e.target.value);
 };

Typescript/React what's the correct type of the parameter for onKeyPress?