TypeScript Tip 02: Three Different Ways to Annotate Event Handlers
When it comes to annotating event handlers, you have several different options. Below we’ll cover three different approaches you can use.
Use inline handlers and let TypeScript do the work for you
In TypeScript, there are several places where type inference is used to provide information when there is no explicit type annotation. The most basic example of this would be:
let counterOne = 0;// ❌ no need to add a type annotation
let counterTwo: number = 0;
In the example above, TypeScript infers that counterOne
is a number
type. We didn’t have to provide the type annotation ourselves!
The same idea applies to event handlers in React:
function Component() {
return (
<button
onClick={(event) => {
/* event will be correctly typed automatically! */
}}
/>
)
}
Typing the right-hand side of =
Often, you’ll need to define the type of your event handler separately. For example, maybe you have written an onClick
function to handle what happens when a user clicks a button. One approach is to provide types for the parameters and return values as shown below:
function Button() {
const handleOnClick = (event: React.MouseEvent<HTMLButtonElement>): void => {
/* do something */
}
return <button onClick={handleOnClick}>click me</button>
}
Typing the left-hand side of =
Alternatively, instead of specifying the types of the function parameters and return values, you can leverage React’s EventHandler types. These types provide the same type-safety as typing the right-hand side of the =
function Button() {
const handleOnClick: React.MouseEventHandler<HTMLButtonElement> = (event) => {
/* do something */
}
return <button onClick={handleOnClick}>click me</button>
}
👋 That’s all for this week; try solving the problems below if you fancy a challenge. Otherwise, come back next week for another tip!
Challenge for the Reader
- What is the difference between the two event handlers?
function handleOnChange(event: React.FormEvent<HTMLInputElement>): void {
// …
}const handleOnChange: ChangeEventHandler<HTMLInputElement> = (event) => {
// ..
}
a) They have two different return types.
b) Nothing is different. They are effectively equivalent.
c) The event parameter in one has different types than in the other.
d) Both a
and c
are correct
a) They have two different return types.
b) Nothing is different. They are effectively equivalent.
c) The event parameter in one has different types than in the other.
d) Both (a) and © are correct
Remove all the TypeScript errors in my custom TS Playground to test your knowledge of Typing Event Handlers
Additional Resources
- https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/#list-of-event-types contains a table of event types React defines.