TypeScript gives React applications compile-time checks for props, state, API models, events, hooks, and reusable components. It is especially valuable in large teams because it makes contracts between components and services explicit.
Typed props
type UserCardProps = {
id: number;
name: string;
isActive: boolean;
};
function UserCard({
id,
name,
isActive
}: UserCardProps) {
return (
<article>
{name} - {isActive ? "Active" : "Inactive"}
</article>
);
}
Event types
function SearchBox() {
function handleChange(
event: React.ChangeEvent<HTMLInputElement>
) {
console.log(event.target.value);
}
return <input onChange={handleChange} />;
}
API model
type Product = {
id: number;
name: string;
price: number;
stock: number;
};
async function getProduct(id: number): Promise<Product> {
const response = await fetch(`/api/products/${id}`);
return response.json();
}
Redux state typing
type RootState = ReturnType<
typeof store.getState
>;
type AppDispatch = typeof store.dispatch;
export const useAppSelector:
TypedUseSelectorHook<RootState> =
useSelector;
export const useAppDispatch = () =>
useDispatch<AppDispatch>();
Discriminated unions
type RequestState =
| { status: "idle" }
| { status: "loading" }
| { status: "success"; data: Product[] }
| { status: "error"; message: string };
Output
TypeScript catches:
<ProductCard price="80000" />
Error:
Type 'string' is not assignable
to type 'number'.
Common mistakes
- Using any everywhere.
- Duplicating types without a shared domain model.
- Ignoring null and undefined.
- Using type assertions to silence legitimate errors.
- Typing API responses without validating untrusted runtime data.
Interview questions
- type vs interface?
- How do you type React events?
- How do you type Redux state?
- What is a discriminated union?
- Why does TypeScript not validate runtime API data?