Typing React Components
TypeScript makes React safer by typing props, state, events, and refs. Learn the patterns used in production React TypeScript codebases — from basic prop types to advanced generic components.
45 min•By Priygop Team•Last updated: Feb 2026
React TypeScript Patterns
Example
// Typing props
type ButtonProps = {
label: string;
variant?: "primary" | "secondary" | "danger";
size?: "sm" | "md" | "lg";
disabled?: boolean;
onClick: () => void;
};
function Button({ label, variant = "primary", size = "md", disabled = false, onClick }: ButtonProps) {
return (
<button className={`btn btn-${variant} btn-${size}`} disabled={disabled} onClick={onClick}>
{label}
</button>
);
}
// Props with children
type CardProps = {
title: string;
children: React.ReactNode; // Any valid JSX content
className?: string;
};
function Card({ title, children, className }: CardProps) {
return (
<div className={`card ${className || ''}`}>
<h2>{title}</h2>
{children}
</div>
);
}
// Typing events
type InputProps = {
value: string;
onChange: (value: string) => void;
onSubmit?: () => void;
};
function SearchInput({ value, onChange, onSubmit }: InputProps) {
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter" && onSubmit) onSubmit();
};
return (
<input
type="text"
value={value}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange(e.target.value)}
onKeyDown={handleKeyDown}
/>
);
}
// Extending HTML element props
type CustomButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
variant: "primary" | "secondary";
isLoading?: boolean;
};
function CustomButton({ variant, isLoading, children, ...rest }: CustomButtonProps) {
return (
<button className={`btn-${variant}`} disabled={isLoading} {...rest}>
{isLoading ? "Loading..." : children}
</button>
);
}