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

Type Guards

Part of the Backend Developer Roadmap

In short

Data from outside, like a webhook or a JSON file, arrives as unknown. Type guards are the checks that tell TypeScript, and you, what it really is before you use it.

Runtime checks that let TypeScript narrow a broad type to a specific one — essential for safely handling untyped input like request bodies or third-party API responses.

The mascot in a guard cap checks an ID card at a hostel gate.

Think of it like this

The hostel gate guard

The guard doesn't let anyone in just because they look like a student. He checks the ID card first. After the check, everyone inside knows you're a resident. A type guard checks a value, and after it TypeScript treats it as that type.

Watch it happen

Narrowing a value step by step

input: unknown
string
object
anything else
has "card"
has "upiId"

1/5The value is unknown. TypeScript won't let you read any property yet.

The big ideas

What you need to know

typeof for primitives

typeof x === "string" or "number" narrows the type inside that if block.

instanceof for classes

err instanceof NotFoundError lets you use that class's fields safely.

in for object shapes

"upiId" in payment checks a property exists, which works well with union types.

Custom guards

A function returning value is User does your own check and teaches TypeScript the result.

See it in code

Walk through the code

ts
1type Card = { method: "card"; last4: string };2type Upi = { method: "upi"; upiId: string };3type Payment = Card | Upi;4 5function describe(p: Payment) {6  if (p.method === "upi") return `UPI ${p.upiId}`;7  return `Card ending ${p.last4}`;8}9 10function isPayment(x: unknown): x is Payment {11  return typeof x === "object" && x !== null && "method" in x;12}13 14const body: unknown = JSON.parse('{"method":"upi","upiId":"riya@okbank"}');15if (isPayment(body)) console.log(describe(body));

1/4A union of two shapes, told apart by the method field. This is a discriminated union.

isPayment here is a light check for learning. In real APIs, a schema library like Zod does these checks thoroughly and gives you the type.

Save yourself the pain

Common mistakes

Oops

Using as Payment to force unknown data into a type.

Do this instead

as only silences the compiler; it checks nothing. Use a real guard or schema validation.

Oops

Writing a custom guard that returns true without really checking.

Do this instead

A guard is a promise to TypeScript. If it lies, you get runtime crashes TypeScript can't warn about.

Your mission

Guard a webhook

~20 min

Quick check

Inside if (typeof value === "number") { ... }, what does TypeScript treat value as?

Go deeper

  1. 1Write a type guard that validates an incoming request body matches your expected shape.
  2. 2Use the `in` operator to narrow a union type based on which property exists.
  3. 3Pair type guards with a validation library (Zod, Joi) for runtime + compile-time safety.

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