48

Typescript 2.3.4, react 15.5.4 and react-bootstrap 0.31.0.

I have a FormControl and I want to do something when the user presses enter.

The control:

<FormControl
  name="keyword"
  type="text"
  value={this.state.keyword}
  onKeyPress={this.handleKeywordKeypress}
  onChange={(event: FormEvent<FormControlProps>) =>{
    this.setState({
      keyword: event.currentTarget.value as string
    });
  }}
/>

What should the definition of the parameter for handleKeywordKeypress be?

I can define it like this:

handleKeywordKeypress= (e: any) =>{
  log.debug("keypress: " + e.nativeEvent.code);
};

That will be called, and it will print keypress: Enter but what should the type of e be so that I can compare the value against (what?) to tell if Enter was pressed.

1

4 Answers 4

62

This seems to work:

handleKeywordKeyPress = (e: React.KeyboardEvent<FormControl>) =>{
  if( e.key == 'Enter' ){
    if( this.isFormValid() ){
      this.handleCreateClicked();
    }
  }
};

The key(Ha ha) here, for me, was to specify React.KeyboardEvent, rather than KeyboardEvent.

Trolling around the React code, I was seeing definitions like:

type KeyboardEventHandler<T> = EventHandler<KeyboardEvent<T>>;

But didn't realise that when I was copy/pasting KeyboardEvent as the parameter type for my handler, the compiler was actually picking up the KeyboardEvent which is some kind of default type defined in the Typescript libraries somewhere (rather than the React definition).

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

1 Comment

If you wanted to simply specify KeyBoardEvent, you have to import it from React, that is all. import {KeyboardEvent} from 'react';
22

Both of the answers above didnt solve my issue, it should be pretty simple and straightforward:

import { KeyboardEvent } from 'react';

const handleKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
   // do stuff
};

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
i don't know what is FormControl, and I believe HTMLInputElement should be the right one since other events are also borrowing from there.
7

The type of onKeyPress should be KeyboardEventHandler<T>, which can be written in either of the following ways:

handleKeywordKeypress: KeyboardEventHandler<FormControl> = e => {
    // use e.keyCode in here
}

or

import { KeyboardEvent } from "react";
handleKeywordKeypress = (e: KeyboardEvent<FormControl>) => {
    // use e.keyCode in here
};

As you identified in your answer, if you go with the second option, you need to specifically use KeyboardEvent from React.

Note that the keyCode is directly available as a property on e; you don't need to access it via the nativeEvent.

Also, the generic type parameter T should be the FormControl component, rather than its props, so you should change your other handler too.

2 Comments

I don't see how your type declaration gets me access to the data I want without casting? See my answer.
You're right, I have edited to improve my answer. Some of it is now quite similar to yours but hopefully there are still some extra useful things in there.
2

The answer for me is a combination of two answers on this page, which only requires React is in scope.

Thanks @Shorn for React.KeyboardEvent @underfrankenwood for HTMLInputElement

import React from "react";
const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
   // ...
};

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.