The Power of TypeScript Utility Types
TypeScript provides a powerful set of utility types that enhance type safety, reduce redundancy, and improve code maintainability. These built-in utility types allow developers to transform, filter, and manipulate types effectively. Whether you're working with objects, unions, or function parameters, utility types can simplify complex type definitions. In this post, we’ll explore essential TypeScript utility types with real-world examples and best practices. 1️⃣ Partial – Make All Properties Optional Partial creates a new type where all properties of T become optional. This is useful for updating objects without requiring all properties. Example: type User = { id: number; name: string; email: string; }; function updateUser(user: User, updates: Partial): User { return { ...user, ...updates }; } const user1: User = { id: 1, name: "Alice", email: "alice@example.com" }; const updatedUser = updateUser(user1, { name: "Bob" }); console.log(updatedUser); // { id: 1, name: "Bob", email: "alice@example.com" } 2️⃣ Readonly – Prevent Object Modification Readonly ensures that all properties of an object cannot be changed after initialization. Example: type Settings = { theme: string; darkMode: boolean; }; const config: Readonly = { theme: "light", darkMode: false }; // config.darkMode = true; // ❌ Error: Cannot assign to 'darkMode' because it is a read-only property. 3️⃣ Pick – Select Specific Properties Pick lets you extract a subset of properties from an existing type. Example: type User = { id: number; name: string; email: string; }; type UserPreview = Pick; const userPreview: UserPreview = { id: 1, name: "Alice" }; // No 'email' property required 4️⃣ Omit – Exclude Specific Properties Omit is the opposite of Pick, allowing you to remove specific properties from a type. Example: type UserWithoutEmail = Omit; const userWithoutEmail: UserWithoutEmail = { id: 1, name: "Alice" }; // No 'email' property allowed 5️⃣ Record – Create Mapped Types Record helps define objects where keys are of type K and values are of type T. Example: type Role = "admin" | "editor" | "user"; const userRoles: Record = { admin: 1, editor: 2, user: 3, }; 6️⃣ Exclude & Extract – Filter Union Types Exclude removes specific types from a union. Extract keeps only the matching types from a union. Example: type Status = "success" | "error" | "pending"; type ActiveStatus = Exclude; // "success" | "pending" type ErrorStatus = Extract; // "error" 7️⃣ NonNullable – Remove null and undefined NonNullable ensures a type doesn’t contain null or undefined. Example: type Name = string | null | undefined; type ValidName = NonNullable; // string

TypeScript provides a powerful set of utility types that enhance type safety, reduce redundancy, and improve code maintainability. These built-in utility types allow developers to transform, filter, and manipulate types effectively. Whether you're working with objects, unions, or function parameters, utility types can simplify complex type definitions.
In this post, we’ll explore essential TypeScript utility types with real-world examples and best practices.
1️⃣ Partial – Make All Properties Optional
Partial
creates a new type where all properties of T
become optional. This is useful for updating objects without requiring all properties.
Example:
type User = {
id: number;
name: string;
email: string;
};
function updateUser(user: User, updates: Partial<User>): User {
return { ...user, ...updates };
}
const user1: User = { id: 1, name: "Alice", email: "alice@example.com" };
const updatedUser = updateUser(user1, { name: "Bob" });
console.log(updatedUser); // { id: 1, name: "Bob", email: "alice@example.com" }
2️⃣ Readonly – Prevent Object Modification
Readonly
ensures that all properties of an object cannot be changed after initialization.
Example:
type Settings = {
theme: string;
darkMode: boolean;
};
const config: Readonly<Settings> = { theme: "light", darkMode: false };
// config.darkMode = true; // ❌ Error: Cannot assign to 'darkMode' because it is a read-only property.
3️⃣ Pick – Select Specific Properties
Pick
lets you extract a subset of properties from an existing type.
Example:
type User = {
id: number;
name: string;
email: string;
};
type UserPreview = Pick<User, "id" | "name">;
const userPreview: UserPreview = { id: 1, name: "Alice" };
// No 'email' property required
4️⃣ Omit – Exclude Specific Properties
Omit
is the opposite of Pick
, allowing you to remove specific properties from a type.
Example:
type UserWithoutEmail = Omit<User, "email">;
const userWithoutEmail: UserWithoutEmail = { id: 1, name: "Alice" };
// No 'email' property allowed
5️⃣ Record – Create Mapped Types
Record
helps define objects where keys are of type K
and values are of type T
.
Example:
type Role = "admin" | "editor" | "user";
const userRoles: Record<Role, number> = {
admin: 1,
editor: 2,
user: 3,
};
6️⃣ Exclude & Extract – Filter Union Types
-
Exclude
removes specific types from a union. -
Extract
keeps only the matching types from a union.
Example:
type Status = "success" | "error" | "pending";
type ActiveStatus = Exclude<Status, "error">; // "success" | "pending"
type ErrorStatus = Extract<Status, "error">; // "error"
7️⃣ NonNullable – Remove null
and undefined
NonNullable
ensures a type doesn’t contain null
or undefined
.
Example:
type Name = string | null | undefined;
type ValidName = NonNullable<Name>; // string