In short
Your variable could be several types. A type guard is a check that tells TypeScript 'inside this if, it's definitely this one', so you can use it safely.
Runtime checks (`typeof`, `instanceof`, custom predicate functions) that let TypeScript narrow a broader type down to a more specific one within a code branch.

Think of it like this
The ticket checker on the train
The TTE checks your ticket and then knows: sleeper or 3AC, so you go to the right coach. Before the check, you could be anyone. A type guard is that ticket check. After it, TypeScript knows exactly which type you have.
Watch it happen
A guard narrows the type
1/4speak(pet) receives a Cat | Dog. You can only use what both have, like name.
The big ideas
What you need to know
typeof for primitives
typeof x === "string" narrows x to a string inside that block.
instanceof for classes
err instanceof Error tells TypeScript err has message and stack.
in for objects
"email" in user narrows to the union members that have an email field.
Your own guard
A function returning value is Type teaches TypeScript a custom check you can reuse.
See it in code
Walk through the code
1type Cat = { name: string; meow: () => void };2type Dog = { name: string; bark: () => void };3 4function isCat(pet: Cat | Dog): pet is Cat {5 return "meow" in pet;6}7 8function speak(pet: Cat | Dog) {9 if (isCat(pet)) pet.meow(); // TypeScript knows it's a Cat10 else pet.bark(); // so this must be a Dog11}12 13function errorText(err: unknown) {14 return err instanceof Error ? err.message : String(err);15}1/4Two shapes that share name but have different methods.
The return type pet is Cat is what makes isCat a type guard. A plain boolean return type wouldn't narrow anything.
Save yourself the pain
Common mistakes
Oops
Using as Cat to silence the error instead of checking.
Do this instead
as only tells TypeScript to trust you. A guard actually checks at runtime.
Oops
Writing a custom guard whose check doesn't match the type it claims.
Do this instead
TypeScript trusts your guard completely. Make the check really prove the type.
Your mission
Guard an API response
Quick check
In a catch block, err has type unknown. How do you safely read err.message?
Go deeper
- 1Write a custom type guard function (`function isX(val): val is X`).
- 2Practice narrowing a union type inside an `if` block and see the type change.
- 3Learn the `in` operator as a type guard for checking object properties.
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.