Introduction
TypeScript utility types are a powerful feature that allows you to transform and manipulate existing types. These built-in types can help you write more flexible and reusable code. In this guide, we'll explore the most commonly used utility types: Partial, Required, Pick, Omit, and more.
1. Partial<Type>
The Partial utility type constructs a type with all properties of Type set to optional. This is incredibly useful when you want to update only some properties of an object.
interface User {
id: number;
name: string;
email: string;
}
// All properties are now optional
type PartialUser = Partial<User>;
// Usage example
function updateUser(id: number, fieldsToUpdate: Partial<User>) {
// Can pass only the fields we want to update
return { id, ...fieldsToUpdate };
}
updateUser(1, { name: 'John' }); // Only update name
2. Required<Type>
The opposite of Partial, Required constructs a type with all properties of Type set to required.
interface Props {
id?: number;
name?: string;
}
const props1: Props = { id: 1 }; // Valid
const props2: Required<Props> = { id: 1 }; // Error: Property 'name' is missing
3. Pick<Type, Keys>
Pick constructs a type by selecting a set of properties Keys from Type.
interface User {
id: number;
name: string;
email: string;
password: string;
}
// Only pick id and name
type UserPreview = Pick<User, 'id' | 'name'>;
const user: UserPreview = {
id: 1,
name: 'John'
};
4. Omit<Type, Keys>
Omit constructs a type by excluding the properties Keys from Type.
interface User {
id: number;
name: string;
email: string;
password: string;
}
// Exclude password
type UserWithoutPassword = Omit<User, 'password'>;
const user: UserWithoutPassword = {
id: 1,
name: 'John',
email: '[email protected]'
};
5. Readonly<Type>
Readonly constructs a type with all properties of Type set to readonly.
interface User {
name: string;
age: number;
}
const user: Readonly<User> = {
name: 'John',
age: 30
};
user.name = 'Jane'; // Error: Cannot assign to 'name' because it is a read-only property
6. Record<Keys, Type>
Record constructs an object type whose property keys are Keys and property values are Type.
type Role = 'admin' | 'user' | 'guest';
const permissions: Record<Role, string[]> = {
admin: ['read', 'write', 'delete'],
user: ['read', 'write'],
guest: ['read']
};
Comparison Table
| Utility Type | Description | Use Case |
|---|---|---|
| Partial<T> | Makes all properties optional | Update operations |
| Required<T> | Makes all properties required | Strict type enforcement |
| Pick<T, K> | Selects specific properties | Creating subsets of types |
| Omit<T, K> | Excludes specific properties | Removing sensitive data |
| Readonly<T> | Makes all properties readonly | Immutable objects |
| Record<K, T> | Creates object with specific keys/values | Mapping types |
Best Practices
- Use Partial for update functions to allow partial updates
- Use Pick when you need only specific properties from a larger type
- Use Omit to exclude sensitive or unnecessary properties
- Combine utility types for complex type transformations
Conclusion
TypeScript utility types are essential tools for writing clean, maintainable code. They allow you to create new types by transforming existing ones, making your code more flexible and reusable. Master these utility types to level up your TypeScript skills!