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.