Introduction
In Part 3, we explored Generics in TypeScript and how they help build reusable, type-safe abstractions. In this part, we’ll focus on one of the most practical and frequently used features in real-world TypeScript projects:
Utility Types
TypeScript utility types help you transform existing types instead of rewriting them, making your code more concise, maintainable, and expressive.
In this article, we’ll cover the most commonly used utility types:
PartialPickOmitRecord
What Are Utility Types?
Utility types are built-in generic types provided by TypeScript that allow you to manipulate and derive new types from existing ones.
They are heavily used in:
- API models
- Form handling
- State management
- Component props
- Backend DTOs
Base Example (Used Across All Examples)
interface User {
id: number;
name: string;
email: string;
isActive: boolean;
}
Partial
What It Does
Partial<T> makes all properties optional.
Syntax
type PartialUser = Partial<User>;
Resulting Type
{
id?: number;
name?: string;
email?: string;
isActive?: boolean;
}
Real-World Use Case: Update API Payload
function updateUser(id: number, data: Partial<User>) {
// send PATCH request
}
updateUser(1, { name: "Nishank" });
✅ Ideal for PATCH requests and partial updates
Pick<T, K>
What It Does
Pick<T, K> creates a type by selecting specific properties from an existing type.
Syntax
type UserPreview = Pick<User, "id" | "name">;
Resulting Type
{
id: number;
name: string;
}
Real-World Use Case: Lightweight API Response
function getUserList(): UserPreview[] {
return [{ id: 1, name: "Nishank" }];
}
✅ Reduces payload size and improves clarity
Omit<T, K>
What It Does
Omit<T, K> creates a new type by excluding specific properties.
Syntax
type UserWithoutEmail = Omit<User, "email">;
Resulting Type
{
id: number;
name: string;
isActive: boolean;
}
Real-World Use Case: Public API Response
function getPublicUser(): UserWithoutEmail {
return {
id: 1,
name: "Nishank",
isActive: true,
};
}
✅ Prevents leaking sensitive data
Record<K, T>
What It Does
Record<K, T> creates an object type where:
- Keys are of type
K - Values are of type
T
Syntax
type RolePermissions = Record<string, boolean>;
Resulting Type
{
[key: string]: boolean;
}
Real-World Use Case 1: Permission Map
type Permissions = Record<"read" | "write" | "delete", boolean>;
const userPermissions: Permissions = {
read: true,
write: false,
delete: false,
};
Real-World Use Case 2: Dynamic Lookup Table
type UserMap = Record<number, User>;
const users: UserMap = {
1: { id: 1, name: "Nishank", email: "n@test.com", isActive: true },
};
Combining Utility Types
Utility types can be composed together.
Example: Editable User
type EditableUser = Partial<Omit<User, "id">>;
✅ Commonly used in forms
Utility Types – Quick Comparison
| Utility Type | Purpose | Common Use Case |
|---|---|---|
| Partial | Make all fields optional | PATCH / update forms |
| Pick | Select specific fields | List / preview views |
| Omit | Exclude fields | Public / safe APIs |
| Record | Key-value mapping | Permissions, lookups |
Best Practices
- Prefer utility types over redefining interfaces
- Combine utility types with generics for flexibility
- Use
PickandOmitto control API contracts - Keep types DRY and reusable
Conclusion
TypeScript utility types are essential tools for writing clean, maintainable, and scalable applications.
By mastering Partial, Pick, Omit, and Record, you can:
- Avoid duplication
- Enforce strong typing
- Improve API design
- Write safer application logic
In the next part, you can explore Advanced Utility Types and Conditional Types.
Happy coding!
