January 10, 2024 3 min read
TypeScriptSoftware EngineeringWeb DevelopmentProgrammingJavaScript

Advanced TypeScript Patterns Every Developer Should Know 🚀

"Make impossible states impossible" - TypeScript's type system at its finest.

Table of Contents

  1. Introduction
  2. Advanced Generic Patterns
  3. Practical Examples
  4. Performance Considerations

Introduction

TypeScript has revolutionized how we write JavaScript applications. In this comprehensive guide, we'll explore advanced patterns that make TypeScript a powerful tool for building robust applications.

Why Advanced Patterns Matter

  1. Type Safety
    • Catch errors at compile time
    • Better IDE support
    • Self-documenting code
  2. Code Reusability
    • DRY principles
    • Maintainable codebase

Advanced Generic Patterns

1. Conditional Types

Here's an example of a powerful conditional type:

type IsArray<T> = T extends any[] ? true : false
type StringOrNumber<T> = T extends string | number ? T : never

// Usage
type Test1 = IsArray<string[]> // true
type Test2 = IsArray<number> // false

2. Mapped Types with Key Remapping

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
}

interface Person {
  name: string
  age: number
}

type PersonGetters = Getters<Person>
// Results in:
// {
//    getName: () => string;
//    getAge: () => number;
// }

Practical Examples

Let's look at a real-world example of a type-safe event emitter:

interface EventMap {
  userLoggedIn: { userId: string; timestamp: number }
  userLoggedOut: { timestamp: number }
  error: { code: number; message: string }
}

class TypeSafeEventEmitter {
  private listeners: Partial<{
    [K in keyof EventMap]: ((data: EventMap[K]) => void)[]
  }> = {}

  on<K extends keyof EventMap>(event: K, callback: (data: EventMap[K]) => void) {
    if (!this.listeners[event]) {
      this.listeners[event] = []
    }
    this.listeners[event]?.push(callback)
  }

  emit<K extends keyof EventMap>(event: K, data: EventMap[K]) {
    this.listeners[event]?.forEach(callback => callback(data))
  }
}

Performance Considerations

When working with complex types, consider the following metrics:

PatternCompile TimeRuntime ImpactType Safety
Generics⭐⭐⭐NoneHigh
Unions⭐⭐NoneHigh
AnyNoneLow

Code Quality Metrics

flowchart LR
    A([Type Safety]) --> B([Code Quality])
    B --> C([Maintainability])
    B --> D([Reliability])
    C --> E([Developer Experience])
    D --> E

Best Practices Checklist

  • Use generics for reusable components
  • Implement proper error handling
  • Document complex type patterns
  • Write unit tests for type behavior

Example Implementation

Here's a practical example of implementing a type-safe API client:

interface ApiResponse<T> {
  data: T
  status: number
  timestamp: number
}

interface ApiError {
  code: number
  message: string
}

async function fetchData<T>(url: string): Promise<ApiResponse<T>> {
  try {
    const response = await fetch(url)
    const data: T = await response.json()

    return {
      data,
      status: response.status,
      timestamp: Date.now(),
    }
  } catch (error) {
    throw {
      code: 500,
      message: error instanceof Error ? error.message : 'Unknown error',
    } as ApiError
  }
}

Advanced Type Utilities

Here's a visualization of how TypeScript's type system works:

Type Hierarchy
└── any
    ├── unknown
    │   ├── primitive types
    │   │   ├── string
    │   │   ├── number
    │   │   └── boolean
    │   └── object types
    │       ├── interfaces
    │       └── classes
    └── never

Keyboard Shortcuts

ActionWindows/LinuxmacOS
Quick FixCtrl + .⌘ + .
Go to DefinitionF12F12
Find ReferencesShift + F12Shift + F12

Conclusion

TypeScript's type system is incredibly powerful when used correctly. By understanding and implementing these advanced patterns, you can:

  1. Write more maintainable code
  2. Catch errors early
  3. Improve team collaboration
  4. Create better developer experiences

💡 Pro Tip: Always start with the simplest type that meets your needs, and only add complexity when necessary.


Share this post

More posts

About

Senior full stack software engineer passionate about building amazing things for the web. Based in Kurdistan, Iraq.

© 2025 Rawand Rebwar. All rights reserved.