learn.colinkim.dev

Generic interfaces and type aliases

Learn how to define types that are parameterized over other types.

Just as functions can be generic, interfaces and type aliases can too. This lets you define reusable type templates that adapt to different data shapes.

Generic type aliases

Type aliases use generic syntax with angle brackets:

type Result<T> = 
  | { ok: true; data: T }
  | { ok: false; error: string };

function fetchUser(): Result<User> {
  // ...
}

function fetchPosts(): Result<Post[]> {
  // ...
}

The Result type captures a common pattern — operations that either succeed with data or fail with an error — while keeping the data type flexible.

Generic interfaces

Interfaces also accept type parameters:

interface Repository<T> {
  findById(id: string): Promise<T | null>;
  findAll(): Promise<T[]>;
  create(data: Omit<T, "id">): Promise<T>;
  update(id: string, data: Partial<T>): Promise<T>;
  delete(id: string): Promise<void>;
}

const userRepository: Repository<User> = {
  // implementation must match the User shape
};

Generic interfaces are common in data access layers, API clients, and state management.

Multiple type parameters

type Mapper<K, V> = Map<K, V>;
type EventHandler<EventName extends string, Payload> = {
  event: EventName;
  handler: (payload: Payload) => void;
};

Generic constraints in type aliases

Constraints work the same way in type aliases and interfaces:

type Identifiable<T extends { id: string }> = {
  entity: T;
  lastModified: Date;
};

type Versioned<T extends { version: number }> = T & {
  history: T[];
};

Extending generic interfaces

Interfaces can extend generic interfaces, passing through or fixing type parameters:

interface Readable<T> {
  read(id: string): Promise<T | null>;
}

interface Writable<T> {
  write(data: T): Promise<void>;
}

interface UserRepository extends Readable<User>, Writable<User> {
  // inherits read(id) and write(data)
}

What to carry forward

  • generic type aliases and interfaces define type templates
  • Result<T> is a common pattern for operations that may succeed or fail
  • generic interfaces are common in data access layers and API clients
  • constraints with extends work the same way in generic types
  • interfaces can extend generic interfaces with fixed or passed-through type parameters

The next lesson covers constraints in depth — how to limit generic types and why it matters.

Progress

Quick checks

No quick checks in this lesson.

Mark lesson manually or answer quick checks to track progress.