CPCODELAB
TypeScript

Introduction to Generics

11 min read

Introduction to Generics

Generics let you write reusable code that works with any type while still maintaining type safety. Instead of using any, you parameterize the type — the caller decides what concrete type fills in the placeholder.

ts
// Without generics — loses type information
function firstAny(arr: any[]): any {
  return arr[0];
}

// With generics — type is preserved
function first<T>(arr: T[]): T {
  return arr[0];
}

const num = first([1, 2, 3]);      // inferred: number
const str = first(["a", "b"]);    // inferred: string

Generic types can also be written as interfaces or type aliases, and generic parameters are inferred at the call site whenever possible.

ts
// Generic interface
interface ApiResponse<T> {
  data: T;
  status: number;
  message: string;
}

// Generic class
class Stack<T> {
  private items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }

  peek(): T | undefined {
    return this.items[this.items.length - 1];
  }
}

Multiple type parameters

ts
function zip<A, B>(a: A[], b: B[]): [A, B][] {
  return a.map((item, i) => [item, b[i]]);
}

const pairs = zip([1, 2, 3], ["a", "b", "c"]);
// [number, string][]
Ready to test yourself?
Practice TypeScript— quiz & coding exercises