█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/TypeScript/Generics
55 minAdvanced

Generics

After this lesson, you will be able to: Use generics: functions, classes, interfaces, constraints, default type parameters.

Generics are the type-level functions. Mastering them unlocks 80% of advanced TS.

Prerequisites:Interfaces vs Type Aliases

Generic functions

Functions that preserve type.

tsx
// Without generic, loses type
function firstAny(arr: any[]): any { return arr[0]; }
// With generic, preserves
function first<T>(arr: T[]): T | undefined {
return arr[0];
}
const x = first([1, 2, 3]); // number | undefined
const y = first(["a", "b"]); // string | undefined
const z = first<string>([]); // explicit
// Multiple generics
function pair<A, B>(a: A, b: B): [A, B] { return [a, b]; }
// Constraint
function longest<T extends { length: number }>(a: T, b: T): T {
return a.length >= b.length ? a : b;
}
longest("abc", "defg"); // ok
longest([1, 2], [3, 4, 5]); // ok
longest(1, 2); // Error, number has no length

Generic interfaces + classes

Same shape; type carried through.

tsx
// Generic interface
interface Box<T> {
value: T;
unwrap(): T;
}
const boxNum: Box<number> = { value: 42, unwrap() { return this.value; } };
// Generic class
class Stack<T> {
private items: T[] = [];
push(item: T) { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
}
const s = new Stack<string>();
s.push("a");

Default type parameters

Provide a fallback when caller doesn't specify.

tsx
type Result<T, E = Error> = { ok: true; data: T } | { ok: false; error: E };
// Most uses: Result<User>, E defaults to Error
// Custom error type: Result<User, ApiError>

Common mistakes only experienced TS devs avoid

Generics that aren't actually used, `<T>` parameters that never appear. Replace with concrete type. Over-constrained generics that don't need the constraint. Forgetting that TS infers generics from arguments. `first([1, 2])` auto-infers T=number; don't always write `first<number>([1, 2])`. Generic parameters with cryptic names. T is convention; for >1 generic, use semantic names: `Map<K, V>`, not `Map<T, U>`.

Quick Check

Why does `function first<T>(arr: T[]): T | undefined` beat `function first(arr: any[]): any`?

Pick the cleanest answer.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Interfaces vs Type Aliases
Back to TypeScript
Advanced Types→