Default Type Parameters

Defaults for T

Like default function parameters, type parameters can have defaults: <T = string>. Callers can skip the type argument when the default is fine.

Example

interface ApiError<D = undefined> {
  code: string;
  message: string;
  details?: D;
}

const simple: ApiError = { code: "NOT_FOUND", message: "Product not found" };

const validation: ApiError<{ field: string; issue: string }[]> = {
  code: "VALIDATION",
  message: "Invalid input",
  details: [{ field: "price", issue: "must be positive" }],
};

console.log(simple.code, simple.details);
console.log(validation.details?.[0].field);

Output

NOT_FOUND undefined
price

Practice

Exercise: Write a generic class Stack<T> with push, pop (returns T | undefined) and a size getter.

Show answer
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 history = new Stack<string>();
history.push("/home");
history.push("/product/42");
console.log(history.pop(), history.size); // /product/42 1