TypeScript Tutorial · Generics and Type Manipulation · Lesson 16 of 25

TypeScript Generics

Write reusable functions, interfaces and classes that keep their types.

Why generics?

A generic function works with many types while keeping the connection between input and output. <T> is a type parameter:

Example 1Try it yourself
function first<T>(items: T[]): T | undefined {
  return items[0];
}
const n = first([10, 20]);        // number | undefined
const s = first(["a", "b"]);      // string | undefined
console.log(n, s?.toUpperCase());

function pair<A, B>(a: A, b: B): [A, B] {
  return [a, b];
}
console.log(pair("age", 36));

Output

10 A
[ 'age', 36 ]

TypeScript usually infers T from the arguments; you can also pass it explicitly: first<string>(["a"]).

Generic interfaces and classes

Example 2Try it yourself
interface ApiResponse<T> {
  data: T;
  error: string | null;
}

class Stack<T> {
  private items: T[] = [];
  push(item: T): void { this.items.push(item); }
  pop(): T | undefined { return this.items.pop(); }
  get size(): number { return this.items.length; }
}

const res: ApiResponse<{ id: number; title: string }[]> = { data: [{ id: 1, title: "Hi" }], error: null };
const stack = new Stack<string>();
stack.push("a");
stack.push("b");
console.log(res.data[0].title, stack.pop(), stack.size);

Output

Hi b 1

Constraints

T extends Something restricts what T can be, so you can use its properties:

Example 3Try it yourself
function longest<T extends { length: number }>(a: T, b: T): T {
  return a.length >= b.length ? a : b;
}
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
console.log(longest("apple", "fig"), longest([1, 2], [1, 2, 3]));
const user = { name: "Ada", age: 36 };
console.log(getProp(user, "age"));
// @ts-expect-error — Argument of type '"email"' is not assignable to parameter of type '"name" | "age"'.
getProp(user, "email");

Output

apple [ 1, 2, 3 ]
36

Test yourself

What does <T extends { length: number }> require of T?

  1. T must be an array
  2. T must have a numeric length property
  3. T must be a number
  4. Nothing
Show answer

Answer: T must have a numeric length property

Practice next