TypeScript has built-in utility types that save you from writing repetitive type definitions. If you use React + TypeScript daily, these five will come up again and again.
Let's look at each one with a real example.
1. Partial<T> — Make everything optional
When you update state, you usually only change some fields. Partial makes every property optional.
type User = {
name: string;
email: string;
age: number;
};
function updateUser(current: User, changes: Partial<User>): User {
return { ...current, ...changes };
}
// Only update the name — no error
updateUser(user, { name: 'Lico' });
Without Partial, TypeScript would complain that email and age are missing.
2. Pick<T, Keys> — Take only what you need
Sometimes a component only needs a few fields from a big type. Pick creates a smaller type from the original.
type User = {
id: string;
name: string;
email: string;
avatar: string;
role: 'admin' | 'user';
};
// This component only cares about name and avatar
type UserCardProps = Pick<User, 'name' | 'avatar'>;
function UserCard({ name, avatar }: UserCardProps) {
return (
<div className="flex items-center gap-2">
<img src={avatar} alt={name} className="w-8 h-8 rounded-full" />
<span>{name}</span>
</div>
);
}
If the User type changes later, UserCard stays in sync automatically.
3. Omit<T, Keys> — Remove what you don't want
The opposite of Pick. Useful when you want almost everything from a type.
type User = {
id: string;
name: string;
email: string;
password: string;
};
// API response should never include the password
type PublicUser = Omit<User, 'password'>;
// Result: { id: string; name: string; email: string }
This is especially handy for API response types where you strip sensitive fields.
4. Record<Keys, Value> — Type-safe dictionaries
When you need an object where every key maps to the same value type, Record is cleaner than writing index signatures.
type Status = 'idle' | 'loading' | 'success' | 'error';
const statusColors: Record<Status, string> = {
idle: 'gray',
loading: 'blue',
success: 'green',
error: 'red',
};
// If you add a new Status later, TypeScript will
// force you to add its color here too. No forgotten cases.
This catches missing keys at compile time, which { [key: string]: string } would not.
5. ReturnType<T> — Infer the return type of a function
Instead of manually writing a type for what a function returns, let TypeScript figure it out.
function createInitialState() {
return {
count: 0,
isOpen: false,
items: [] as string[],
};
}
type AppState = ReturnType<typeof createInitialState>;
// Result: { count: number; isOpen: boolean; items: string[] }
This is great for custom hooks. Change the hook's return value, and every consumer type updates automatically.
When to use which?
| Situation | Utility type |
|---|---|
| Update only some fields | Partial |
| Component needs a few fields from a big type | Pick |
| Need everything except certain fields | Omit |
| Object where all values share one type | Record |
| Want the type a function returns | ReturnType |
These five cover maybe 80% of the utility type situations you'll hit in a React + TypeScript codebase. They're all built into TypeScript — no imports needed.
Happy Coding! 🙂
Top comments (0)