Skip to main content

Advanced TypeScript Patterns for Better Code Quality

10 min read
TypeScript
Programming
Best Practices

Advanced TypeScript Patterns for Better Code Quality

TypeScript's type system is incredibly powerful. Let's explore some advanced patterns that can significantly improve your code quality.

Discriminated Unions

Discriminated unions help create type-safe state machines:

type LoadingState = 
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: string }
  | { status: 'error'; error: Error };

function handleState(state: LoadingState) {
  switch (state.status) {
    case 'success':
      // TypeScript knows state.data exists here
      console.log(state.data);
      break;
    case 'error':
      // TypeScript knows state.error exists here
      console.error(state.error);
      break;
  }
}

Conditional Types

Conditional types enable type transformations based on conditions:

type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true
type B = IsString<number>; // false

// Practical example: Extract promise type
type Awaited<T> = T extends Promise<infer U> ? U : T;

type Result = Awaited<Promise<string>>; // string

Type Guards

Custom type guards provide runtime type checking:

interface User {
  id: string;
  name: string;
}

function isUser(value: unknown): value is User {
  return (
    typeof value === 'object' &&
    value !== null &&
    'id' in value &&
    'name' in value
  );
}

function processData(data: unknown) {
  if (isUser(data)) {
    // TypeScript knows data is User here
    console.log(data.name);
  }
}

Mapped Types

Transform existing types into new ones:

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

type Partial<T> = {
  [P in keyof T]?: T[P];
};

interface User {
  id: string;
  name: string;
  email: string;
}

type ReadonlyUser = Readonly<User>;
type PartialUser = Partial<User>;

Conclusion

These advanced TypeScript patterns help catch errors at compile time and make your code more maintainable. Start incorporating them into your projects to level up your TypeScript skills.