Handling events in a React app is one of those things you do a hundred times before you even think about it. With TypeScript you get compile-time checks that catch the dumb mistakes before they reach the browser. Here are two ways to type your event handlers.
The Code
import * as React from 'react';
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
console.log('Input value:', e.target.value);
};
const handleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Enter') {
e.preventDefault();
console.log('Enter key pressed');
}
};
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
console.log('Button clicked');
};
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log('Form submitted');
};
function EventHandlingExplicit() {
return (
<div>
<input type="text" onChange={handleInputChange} onKeyDown={handleKeyPress} />
<button onClick={handleClick}>Click me</button>
<form onSubmit={handleFormSubmit}>
<button type="submit">Submit Form</button>
</form>
</div>
);
}Dependencies
npm install reactBreakdown
First approach annotates the parameter directly -- full event type on the function signature. More explicit, slightly more verbose, but you see exactly what you're dealing with at a glance.
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => { ... };Second approach uses the EventHandler shorthand. Generic parameter only needs the element type. Events like KeyboardEvent or FormEvent don't even need one.
const handleClick: React.MouseEventHandler = (e) => { ... };Both are type safe. The explicit version communicates intent louder. The EventHandler version is shorter and keeps the function body cleaner when you have many handlers. Use what your team finds easier to read.
Happy Coding
