100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What Are Generics in TypeScript and Why Use Them?

Learn what generics are in TypeScript, how type parameters work, and why they beat any — with a hands-on code example.

mediumQ207 of 224 in Web Development Est. time: 5 minsLast updated:
Open Code Lab

Expected Interview Answer

Generics let you write functions, interfaces, and classes that work with a type parameter decided at the call site, so you get full type safety without duplicating logic for every concrete type or falling back to an unsafe “any”.

Instead of writing separate functions like firstString(arr: string[]) and firstNumber(arr: number[]), a generic function first<T>(arr: T[]): T accepts a type parameter T that TypeScript infers or you specify explicitly, and the return type automatically matches whatever array element type was passed in. This preserves the specific type all the way through the call, so calling first(["a", "b"]) correctly returns a string, while first([1, 2]) returns a number, with the compiler catching any misuse downstream. Generics extend beyond functions to interfaces (interface Box<T> { value: T }) and classes, and can be constrained with extends to require a shape, like function getLength<T extends { length: number }>(x: T). The core benefit is reusability without losing precision: any would also let one function handle every type, but it discards all type information, whereas generics keep the relationship between input and output types intact.

  • Reuses a single implementation across many concrete types without duplication
  • Preserves precise input-to-output type relationships that `any` would discard
  • Constraints (extends) let you require a minimal shape while staying generic
  • Enables strongly typed, reusable data structures like generic Box or Result types

AI Mentor Explanation

Generics are like a kit bag template that adapts to whichever format is specified at the time of packing — Test, ODI, or T20 — while still guaranteeing the bag always matches that format’s actual requirements. Instead of building three separate bag designs, one template takes a “format” parameter and produces the exact right contents each time. Pack it for T20 and you are guaranteed T20 gear inside, not a mismatched Test kit. That single-template-adapts-per-call-while-staying-precise pattern is exactly what a generic function does in TypeScript.

Step-by-Step Explanation

  1. Step 1

    Declare a type parameter

    Write <T> after the function, interface, or class name to introduce a stand-in type.

  2. Step 2

    Use T in the signature

    Reference T in parameters and the return type so their relationship stays linked.

  3. Step 3

    Call site infers or specifies T

    TypeScript infers T from the argument passed, or you supply it explicitly like first<number>([1,2]).

  4. Step 4

    Compiler enforces the concrete type

    Every usage downstream is checked against the specific type T resolved to for that call.

What Interviewer Expects

  • Ability to write a simple generic function and explain type parameter inference
  • Clear distinction between generics and using `any` (precision preserved vs discarded)
  • Knowledge of generic constraints via extends
  • Awareness of generics in interfaces/classes, not just functions

Common Mistakes

  • Confusing generics with `any`, which loses all type information
  • Overusing generics where a simple union or concrete type would be clearer
  • Forgetting to constrain a generic when the function actually needs a specific shape
  • Not realizing the type parameter name (T, K, V) is just a convention, not special syntax

Best Answer (HR Friendly)

Generics let you write one function or data structure that works for many different types while still being fully type-checked. Instead of writing a separate version of a function for strings and another for numbers, or giving up and using `any`, you write it once with a stand-in type, and TypeScript fills in and checks the real type each time you use it.

Code Example

A generic function and a generic interface
function first<T>(arr: T[]): T | undefined {
  return arr[0]
}

const a = first(['x', 'y', 'z']) // inferred as string | undefined
const b = first([1, 2, 3]) // inferred as number | undefined

interface Box<T> {
  value: T
}

function unwrap<T>(box: Box<T>): T {
  return box.value
}

function getLength<T extends { length: number }>(item: T): number {
  return item.length // constrained: T must have a length property
}

Follow-up Questions

  • How do generic constraints with extends differ from unconstrained generics?
  • What is the difference between `any` and `unknown`, and how does that relate to generics?
  • How would you write a generic Result<T, E> type for handling success/error outcomes?
  • How does TypeScript infer generic type parameters when multiple arguments are involved?

MCQ Practice

1. What is the main purpose of generics in TypeScript?

Generics enable reusable, type-safe code by parameterizing the type instead of hardcoding it or using any.

2. How does a generic function differ from one using `any`?

Generics keep the concrete type linked through the function, while any loses all type checking.

3. What does `function getLength<T extends { length: number }>(x: T)` express?

The extends clause constrains T to any type with a compatible length property, while remaining generic.

Flash Cards

What is a generic type parameter?A stand-in type (like T) filled in with a concrete type at the call site.

Generics vs any?Generics preserve type relationships; any discards all type safety.

What does `T extends Shape` do?Constrains the generic to types compatible with Shape while staying generic.

Where can generics be used?Functions, interfaces, classes, and type aliases.

1 / 4

Continue Learning