PureTools

TypeScript Utility Types: The Practical Cheatsheet

PureTools Team· 7 min read
TypeScript Utility Types: The Practical Cheatsheet

TypeScript Utility Types: Beyond the Basics

TypeScript's built-in utility types let you transform types without rewriting them. Instead of creating UserUpdate manually with all optional fields, use Partial<User>. They're composable, powerful, and once you learn them, you'll use them everywhere.

The Essential Ones

interface User {
  id: number;
  name: string;
  email: string;
  role: 'admin' | 'user';
  createdAt: Date;
}

Partial<T> — makes all properties optional:

// All fields become optional
type UserUpdate = Partial<User>;
// { id?: number; name?: string; email?: string; ... }

function updateUser(id: number, data: Partial<User>) {
  // Can pass { name: 'New Name' } without other fields
}

Required<T> — makes all properties required (opposite of Partial):

interface Config {
  host?: string;
  port?: number;
  debug?: boolean;
}

type StrictConfig = Required<Config>;
// { host: string; port: number; debug: boolean; }

Pick<T, K> — select specific properties:

type UserPreview = Pick<User, 'id' | 'name'>;
// { id: number; name: string; }

// Great for API response types
type LoginResponse = Pick<User, 'id' | 'email' | 'role'>;

Omit<T, K> — remove specific properties:

type CreateUserInput = Omit<User, 'id' | 'createdAt'>;
// { name: string; email: string; role: 'admin' | 'user'; }

// Use for forms where some fields are auto-generated

Record<K, V> — create an object type with specific key and value types:

type UserRoles = Record<string, 'admin' | 'user' | 'guest'>;
// { [key: string]: 'admin' | 'user' | 'guest'; }

// Typed dictionaries
const permissions: Record<User['role'], string[]> = {
  admin: ['read', 'write', 'delete'],
  user: ['read'],
};

String Manipulation Types

type Upper = Uppercase<'hello'>;       // 'HELLO'
type Lower = Lowercase<'HELLO'>;       // 'hello'
type Cap = Capitalize<'hello'>;        // 'Hello'
type Uncap = Uncapitalize<'Hello'>;    // 'hello'

Advanced Combinations

// Make only some fields optional
type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type UserWithOptionalEmail = PartialBy<User, 'email'>;

// Make only some fields required
type RequiredBy<T, K extends keyof T> = T & Required<Pick<T, K>>;

// Readonly version for immutable state
type ImmutableUser = Readonly<User>;

// Extract function return type
function getUser() { return { id: 1, name: 'Alice' }; }
type UserResult = ReturnType<typeof getUser>;
// { id: number; name: string; }

// Extract function parameters
type GetUserParams = Parameters<typeof getUser>;
// []

Real-World Patterns

// API endpoint types
interface ApiEndpoints {
  '/users': { GET: User[]; POST: Omit<User, 'id'>; };
  '/users/:id': { GET: User; PUT: Partial<User>; DELETE: void; };
}

// Event handler map
type EventMap = Record<string, (...args: any[]) => void>;

// Component props with defaults
type PropsWithDefaults<P, D extends Partial<P>> = Omit<P, keyof D> & Partial<D>;

Format your TypeScript: JavaScript/TypeScript Formatter — paste code, get formatted output instantly.