Loading introduction
Loading stats
Loading about
Loading posts
Loading article
Skip to content
Md Nayeem Hossain
Explorer
home.tsx
typescript-advanced-patterns.md
typescript-advanced-patterns.md
blog.json

// Frontend

TypeScript Advanced Patterns for Professional Developers

Master advanced TypeScript patterns including generics, utility types, and type-safe design patterns.

Md Nayeem HossainDec 10, 202413 min read

TypeScript Advanced Patterns#

Most developers know the basics of TypeScript: strings, numbers, and interfaces. But TypeScript's type system is incredibly powerful (Turing complete, actually!). Mastering advanced patterns allows you to write libraries and utilities that are robust and flexible.

Generics: Flexible Reusable Code#

Generics allow you to write code that works with a variety of types rather than a single one. Think of them as "variables for types."

typescript
1// Without generics, we lose type information2function getFirst(arr: any[]) {3  return arr[0]; // Return type is 'any'4}5 6// With generics7function getFirst<T>(arr: T[]): T | undefined {8  return arr[0];9}10 11const num = getFirst([1, 2, 3]); // Type is 'number'12const str = getFirst(["a", "b"]); // Type is 'string'

Utility Types#

TypeScript comes with built-in utilities that transform types.

  • Partial<T>: Makes all properties optional.
  • Pick<T, K>: Selects a subset of properties.
  • Omit<T, K>: Removes a subset of properties.
typescript
1interface User {2  id: number;3  name: string;4  email: string;5  passwordHash: string;6}7 8// When updating a user, we might only provide some fields9type UpdateUserDto = Partial<User>;10 11// When displaying a user, we NEVER want to show the password12type UserProfile = Omit<User, 'passwordHash'>;

Discriminated Unions#

This is my favorite pattern for state management (like in Redux or useReducer). It uses a common literal field (usually type or kind) to let TypeScript narrow down the type.

typescript
1type APIState =2  | { status: "loading" }3  | { status: "success"; data: User[] }4  | { status: "error"; error: string };5 6function handleState(state: APIState) {7  if (state.status === "loading") {8    // TypeScript knows 'data' and 'error' don't exist here9    return "Loading...";10  }11 12  if (state.status === "success") {13    // TypeScript knows 'data' exists here!14    return `Loaded ${state.data.length} users`;15  }16 17  if (state.status === "error") {18    return `Error: ${state.error}`;19  }20}

This pattern makes "impossible states" impossible to represent in your code, eliminating entire classes of bugs.

#TypeScript#JavaScript#Types#Best Practices
OlderREST API Design: Best Practices and StandardsNewer CI/CD Pipeline with GitHub Actions: Complete Setup Guide

Outline

  • TypeScript Advanced Patterns
  • Generics: Flexible Reusable Code
  • Utility Types
  • Discriminated Unions