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: "[email protected]" };
const updatedUser = updateUser(user1, { name: "Bob" });

console.log(updatedUser); // { id: 1, name: "Bob", email: "[email protected]" }

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

🚀 Conclusion

TypeScript utility types enhance code maintainability, reduce repetition, and improve type safety. Whether you need to make properties optional, readonly, or filter union types, these utilities are incredibly powerful.

By leveraging these built-in tools, you can write more efficient, error-free TypeScript code.

💡 Which utility type do you use the most? Let me know in the comments! 👇


📌 Stay tuned for the next post: Server Components vs. Server-Side Rendering in Next.js 15!