Back to blog

TypeScript Patterns for Better Code

A collection of practical TypeScript patterns that will help you write safer, more maintainable code in your everyday projects.

TypeScript has evolved far beyond a simple type layer on top of JavaScript. Here are some patterns that can dramatically improve your code quality.

Discriminated Unions

One of the most powerful TypeScript patterns is the discriminated union. It lets you model state machines with complete type safety.

type Result<T> =
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error }
  | { status: 'loading' }

function handleResult(result: Result<User>) {
  switch (result.status) {
    case 'success':
      console.log(result.data) // TypeScript knows data exists
      break
    case 'error':
      console.error(result.error) // TypeScript knows error exists
      break
    case 'loading':
      console.log('Loading...')
      break
  }
}

The satisfies Operator

The satisfies operator lets you validate that an expression matches a type without changing the inferred type.

const config = {
  port: 3000,
  host: 'localhost',
  debug: true,
} satisfies Record<string, string | number | boolean>

// config.port is still inferred as number, not string | number | boolean

Template Literal Types

Template literal types let you create precise string types from other types.

type EventName = 'click' | 'focus' | 'blur'
type Handler = `on${Capitalize<EventName>}` // 'onClick' | 'onFocus' | 'onBlur'

These patterns are not just theoretical — they solve real problems in everyday code. Start incorporating them into your projects and watch your code quality improve.