What are TypeScript utility types?

Utility types are built-in generic types that transform existing types - Partial, Required, Pick, Omit, Readonly, Record, and more are available out of the box.

TypeScript

Overview

TypeScript ships with a set of generic utility types that perform common type transformations without you having to write them yourself. They are essential for keeping types DRY - derive the types you need from a single source of truth.

Key Points

  • •`Partial<T>` - all properties become optional.
  • •`Required<T>` - all properties become required (removes `?`).
  • •`Readonly<T>` - all properties become `readonly`.
  • •`Pick<T, K>` - keeps only the listed keys.
  • •`Omit<T, K>` - removes the listed keys.
  • •`Record<K, V>` - creates an object type with keys `K` and values `V`.
  • •`ReturnType<T>`, `Parameters<T>`, `Awaited<T>` - introspect functions and Promises.

Examples

Partial and Required

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

// All optional - useful for update/patch operations
type UserUpdate = Partial<User>;
// { id?: number; name?: string; email?: string }

// All required - reverse of Partial
type StrictUser = Required<UserUpdate>;
// { id: number; name: string; email: string }

Pick and Omit

typescript
interface Article {
  id: number;
  title: string;
  content: string;
  authorId: number;
  publishedAt: Date;
}

// Keep only what you need for the preview card
type ArticlePreview = Pick<Article, 'id' | 'title' | 'publishedAt'>;

// Everything except the body (for a list API response)
type ArticleSummary = Omit<Article, 'content'>;

Record: typed key-value maps

typescript
type Role = 'admin' | 'editor' | 'viewer';
type Permission = { read: boolean; write: boolean; delete: boolean };

const permissions: Record<Role, Permission> = {
  admin:  { read: true,  write: true,  delete: true  },
  editor: { read: true,  write: true,  delete: false },
  viewer: { read: true,  write: false, delete: false },
};

ReturnType and Parameters

typescript
async function fetchUser(id: number): Promise<{ name: string; age: number }> {
  // ...
}

type FetchUserReturn = Awaited<ReturnType<typeof fetchUser>>;
// { name: string; age: number }

type FetchUserParams = Parameters<typeof fetchUser>;
// [id: number]

Derive types from functions so the source of truth is the implementation, not a separate type declaration.

Pro Tip

When you find yourself writing a type that is "like X but with field Y removed" or "like X but all optional", reach for `Omit`, `Partial`, or `Pick` before writing the type from scratch. Derived types stay in sync automatically when the base type changes.