Typing Functional Components
On this page
Typing Philosophy
- Type at boundaries. Props define the public contract.
- Let TypeScript infer return types unless there is a specific reason to enforce them.
- Keep component public APIs minimal and stable.
Preferred Pattern
type ButtonProps = {
label: string;
onClick: () => void;
disabled?: boolean;
};
function Button({ label, onClick, disabled }: ButtonProps) {
return (
<button onClick={onClick} disabled={disabled}>
{label}
</button>
);
}
Why Not React.FC
- React.FC implicitly adds children even when not intended.
- It hides explicit control over return type and generics.
- Explicit function typing improves clarity and long term maintainability.
Boundary Discipline
- Never allow implicit any at component boundaries.
- Validate external data before assigning to typed props.
- Avoid widening types unnecessarily.
Failure Modes
- Implicit any leaking into the component tree.
- Overly broad types allowing invalid states.
- Unsafe type assertions masking runtime bugs.
- Public prop types changing frequently and breaking consumers.
Code Review Checklist
- Props are explicitly typed.
- No any at component boundary.
- No unnecessary type assertions.
- Public API surface is minimal.