Event Handler Contract
Problem
Event handlers are untyped, allowing functions with wrong signatures to be passed without warning. Developers access event properties that don’t exist, mistype event types, or pass handlers that expect different event shapes. Callback parameters are unclear, making it hard to know what data is available when handling clicks, form submissions, or custom events.
Solution
Define consistent function signatures for event callbacks to establish predictable interfaces. This makes components easier to integrate and reduces confusion about what arguments handlers receive.
Example
This example demonstrates defining type-safe event handlers with explicit parameter and return type signatures.
// Define the contract for button props including typed event handler
interface ButtonProps {
// onClick must accept a MouseEvent and return void
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
}
function Button({ onClick }: ButtonProps) {
// TypeScript ensures onClick matches the signature
return <button onClick={onClick}>Click</button>;
}
Benefits
- Provides type safety for event handler parameters and return types
- Makes it clear what data is available in event handlers
- Catches errors at compile time when wrong handlers are passed
- Improves IDE autocomplete for event properties
- Documents expected event handler signatures
Tradeoffs
- Adds verbosity with explicit type definitions
- Can feel like overkill for simple onClick handlers
- Requires TypeScript or PropTypes to enforce
- May need complex generics for flexible event types
- Learning curve for developers unfamiliar with event typing