2 min read

TypeScript Utility Types

TypeScript provides several global utility types to facilitate common type transformations. These allow you to create new types based on existing ones without rewriting code.

1. Partial

Constructs a type with all properties of Type set to optional. This is useful when updating objects where you might only change a subset of fields (like a PATCH request).

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

function updateUser(user: User, fieldsToUpdate: Partial<User>) {
  return { ...user, ...fieldsToUpdate };
}

const user1: User = { id: 1, name: "Alice", email: "alice@example.com" };

// Valid: We only provide 'email', and TypeScript doesn't complain about missing 'id' or 'name'
const user2 = updateUser(user1, { email: "alice@newdomain.com" });

2. Pick<Type, Keys>

Constructs a type by picking a set of properties Keys from Type. This is useful for creating "preview" objects or DTOs (Data Transfer Objects).

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick<Todo, "title" | "completed">;

const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
  // description: "..." // Error: 'description' is not part of TodoPreview
};

3. Omit<Type, Keys>

The opposite of Pick. Constructs a type by picking all properties from Type and then removing Keys.

interface Todo {
  title: string;
  description: string;
  completed: boolean;
  createdAt: number;
}

// We want everything EXCEPT 'createdAt'
type TodoInfo = Omit<Todo, "createdAt">;

const todoInfo: TodoInfo = {
  title: "Pick up kids",
  description: "Kindergarten closes at 5pm",
  completed: false
};

4. Record<Keys, Type>

Constructs an object type whose property keys are Keys and whose property values are Type. This is cleaner than defining an index signature manually.

type CatName = "miffy" | "boris" | "mordred";

const cats: Record<CatName, number> = {
  miffy: 10,
  boris: 5,
  mordred: 16,
};

programming/javascript/typescript/typescript