1

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 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Tried that as well, updating OP to reflect this.
Looks like event.currentTarget and the event type you mentioned did the trick. I had tried it event.currentTarget before, but I must have had some other type applied to the event and it failed. It works now. Accepted as the right answer.
React resuses event so you can't access them in n asynchronous way, I think that's way it probably does not work with await.
I updated the OP with the final and working code I'm running. Thanks for your help.
2

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
 */

Comments

0

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?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.