Asher Cohen
Back to posts

TypeScript Advanced Types Guide

Master TypeScript's powerful type system with advanced type features and patterns

Introduction

TypeScript's type system goes far beyond basic types. Advanced types enable you to express complex relationships, create flexible APIs, and catch bugs at compile time.

Type Unions and Intersections

Union Types

Union types represent a value that can be one of several types.

type Status = 'pending' | 'loading' | 'success' | 'error';
type Id = string | number;

function printId(id: Id) {
  console.log(id.toString());
}

Intersection Types

Intersection types combine multiple types into one.

type A = { a: number };
type B = { b: string };
type C = A & B; // { a: number; b: string }

const obj: C = { a: 1, b: 'hello' };

Type Guards and Type Predicates

Type guards narrow down types within conditional blocks.

function isString(value: unknown): value is string {
  return typeof value === 'string';
}

function process(value: string | number) {
  if (isString(value)) {
    // TypeScript knows value is string here
    return value.toUpperCase();
  }
  // TypeScript knows value is number here
  return value.toFixed(2);
}

Mapped Types

Mapped types transform existing types by modifying their properties.

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

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

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

type ReadOnlyUser = ReadOnly<User>;
type PartialUser = Partial<User>;

Conditional Types

Conditional types select types based on conditions.

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

type A = IsString<'hello'>; // true
type B = IsString<123>; // false

Infer Keyword

Extract types from complex structures.

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;

type MyFunc = () => string;
type Result = ReturnType<MyFunc>; // string

Template Literal Types

Create string types with pattern matching.

type EventName = `on${Capitalize<string>}`;
type Handler = (event: EventName) => void;

const handler: Handler = (event) => {
  // event is "onClick", "onSubmit", etc.
};

Key Features to Explore

For comprehensive coverage, dive into these topics:

Best Practices

Start Simple

Don't over-engineer types. Use the simplest type that works.

Document Complex Types

Add comments explaining why a type is complex.

Use Generics Wisely

Generics provide flexibility but can hurt readability if overused.

Leverage Inference

Let TypeScript infer types when they're obvious.

Resources

The official TypeScript documentation is an excellent resource for deep dives into advanced types.

Conclusion

Mastering advanced types takes practice, but the payoff is worth it. You'll write safer, more maintainable code with better tooling support.

#typescript #types #programming