Stop 04 · JavaScript & TypeScript for BackendTopics · 8/12

Generics

Part of the Backend Developer Roadmap

In short

Every API response has the same wrapper but different data inside. Generics let you write that wrapper once and still keep exact types for users, orders or anything else.

Reusable, type-safe functions and classes that work across many data types — commonly used for typing API response wrappers and repository/service patterns.

The mascot arranges identical clear containers holding rice, biscuits and marbles.

Think of it like this

Identical clear containers

Your mother's kitchen has identical clear containers. One holds rice, one biscuits, one your marbles. The box is the same design, but you always know what's inside. A generic like Box<T> is that container: same shape, any content, clearly known.

Watch it happen

One wrapper, many contents

ApiResponse<T>
0
T = User
1
T = Order[]
2
T = null
3

1/4ApiResponse<T> has ok, data: T and an optional error. T is a placeholder for the content type.

The big ideas

What you need to know

T is a type variable

Like a function parameter, but for types. The caller decides what T is, or TypeScript infers it.

Write once, stay typed

One generic function replaces many copies, and you don't lose type safety like you would with any.

Constrain with extends

<T extends { id: string }> means T can be anything, as long as it has an id.

You already use them

Array<string>, Promise<User> and Record<string, number> are all generics.

See it in code

Walk through the code

ts
1type ApiResponse<T> = {2  ok: boolean;3  data: T;4  error?: string;5};6 7function success<T>(data: T): ApiResponse<T> {8  return { ok: true, data };9}10 11function findById<T extends { id: string }>(items: T[], id: string): T | undefined {12  return items.find((item) => item.id === id);13}14 15const res = success({ id: "u1", email: "a@x.in" });16res.data.email; // typed as string, no casting needed

1/4A generic response type. T stands for whatever data this response carries.

You never wrote success<User>. TypeScript looked at the argument and inferred T for you.

Save yourself the pain

Common mistakes

Oops

Writing getUserResponse, getOrderResponse and getCartResponse types separately.

Do this instead

Write one ApiResponse<T> and plug in User, Order or Cart.

Oops

Using <T> where it isn't needed, like function log<T>(msg: T) that just prints.

Do this instead

Use a generic only when it connects types, like input to output. Otherwise a normal type is clearer.

Your mission

A typed repository

~25 min

Quick check

What does <T extends { id: string }> mean?

Go deeper

  1. 1Write a generic `ApiResponse<T>` type wrapping your API's success/error responses.
  2. 2Build a generic repository function that fetches typed data from a database.
  3. 3Learn generic constraints to restrict what types are allowed.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge