TypeScript offers several utility types that can make your code cleaner, more efficient, and easier to maintain. Utility types help transform existing types and provide more flexibility in handling type-related problems. In this blog, we'll discuss some of the most commonly used utility types: Omit, Exclude, Partial, Pick, Record, Readonly, and Required. For each utility type, we'll look at a real-world example to demonstrate how to use it effectively.
1. Omit
Omit creates a type by removing properties from another type.
Example:
Suppose you have a User type, but you want to create a new type that excludes sensitive information like password.
type User = {
id: number;
name: string;
email: string;
password: string;
};
type UserWithoutPassword = Omit<User, "password">;
const user: UserWithoutPassword = {
id: 1,
name: "John Doe",
email: "john@example.com",
};2. Exclude
Exclude creates a type by excluding certain types from a union.
Example:
You have a union type representing possible event names and want to exclude a specific event.
type Events = "click" | "scroll" | "mousemove";
type MouseEvents = Exclude<Events, "scroll">;
const event: MouseEvents = "click";3. Partial
Partial makes all properties of a type optional.
Example:
You want to update a user profile, but the update form doesn't require all fields to be filled out.
type UserProfile = {
id: number;
name: string;
email: string;
age: number;
};
type PartialUserProfile = Partial<UserProfile>;
const updateUserProfile = (profile: PartialUserProfile) => {
// Update logic here
};
updateUserProfile({ name: "Jane Doe" });4. Pick
Pick creates a type by selecting a subset of properties from another type.
Example:
You want to create a type for a summary view of a user, showing only id and name.
type User = {
id: number;
name: string;
email: string;
password: string;
};
type UserSummary = Pick<User, "id" | "name">;
const userSummary: UserSummary = {
id: 1,
name: "John Doe",
};5. Record
Record creates a type with a set of properties of a specific type.
Example:
You want to create a map where each user ID maps to a user profile.
type UserProfile = {
id: number;
name: string;
email: string;
};
type UserMap = Record<number, UserProfile>;
const users: UserMap = {
1: { id: 1, name: "John Doe", email: "john@example.com" },
2: { id: 2, name: "Jane Smith", email: "jane@example.com" },
};6. Readonly
Readonly makes all properties of a type immutable.
Example:
You have a configuration object that shouldn't be modified after creation.
type Config = {
apiUrl: string;
timeout: number;
};
const config: Readonly<Config> = {
apiUrl: "https://api.example.com",
timeout: 5000,
};
// config.apiUrl = 'https://api.newexample.com'; // Error: Cannot assign to 'apiUrl' because it is a read-only property.7. Required
Required makes all properties of a type mandatory.
Example:
You have a user form where all fields must be filled out.
type UserForm = {
name?: string;
email?: string;
age?: number;
};
type RequiredUserForm = Required<UserForm>;
const userForm: RequiredUserForm = {
name: "Alice",
email: "alice@example.com",
age: 30,
};Learn more about utility types here. Each utility type serves a specific purpose and can simplify complex type manipulations in real-world applications. Start using these utility types to streamline your TypeScript development process today!