Utility Types

Built-in types that transform other types. Use them instead of manually rewriting shapes.

The Essentials

interface User {
  name: string;
  email: string;
  age: number;
}

type PartialUser = Partial<User>;       // all fields optional
type ReadonlyUser = Readonly<User>;     // all fields readonly
type NameAndEmail = Pick<User, "name" | "email">;  // subset of fields
type WithoutAge = Omit<User, "age">;    // all fields except age

Common Patterns

Partial for updates

function updateUser(id: string, updates: Partial<User>) {
  // updates can have any subset of User fields
}

updateUser("123", { name: "Alice" }); // OK - only updating name

Record for dictionaries

type StatusCounts = Record<"active" | "inactive" | "pending", number>;

const counts: StatusCounts = {
  active: 10,
  inactive: 3,
  pending: 5,
};

Extract and Exclude for unions

type Status = "success" | "error" | "pending" | "cancelled";
type ActiveStatus = Extract<Status, "success" | "pending">;  // "success" | "pending"
type FailedStatus = Exclude<Status, "success" | "pending">;  // "error" | "cancelled"

ReturnType and Parameters

function createUser(name: string, age: number) {
  return { id: crypto.randomUUID(), name, age };
}

type NewUser = ReturnType<typeof createUser>;   // { id: string; name: string; age: number }
type Args = Parameters<typeof createUser>;       // [name: string, age: number]

Quick Reference

TypePurpose
Partial<T>Make all properties optional
Required<T>Make all properties required
Readonly<T>Make all properties readonly
Pick<T, K>Select specific properties
Omit<T, K>Remove specific properties
Record<K, V>Object type with key type K and value type V
Extract<T, U>Extract union members assignable to U
Exclude<T, U>Remove union members assignable to U
ReturnType<T>Get function return type
Parameters<T>Get function parameter types as tuple
NonNullable<T>Remove null and undefined from union

Tip: Use satisfies with utility types for the best of both worlds - inference plus validation:

const config = {
  port: 3000,
  host: "localhost",
} satisfies Partial<Config>;
// TypeScript still infers the specific literal types