What are Type Guards in TypeScript?
Learn TypeScript type guards: typeof, instanceof, in, and custom type predicates that narrow union types for safe, error-free, assertion-free code.
Expected Interview Answer
A type guard is an expression or function that narrows a value to a more specific type within a code branch, letting TypeScript safely allow operations that depend on that narrower type.
Built-in guards include 'typeof' for primitives, 'instanceof' for class instances, the 'in' operator for property presence, and equality checks that narrow unions. You can also write custom type guards using a return type predicate like 'value is Fish', which tells the compiler that a true result means the argument has that type. Inside a guarded branch, the type is narrowed, so member access and method calls become type-safe without casts.
- Enables safe access to union-specific members
- Removes the need for unsafe type assertions
- Improves autocompletion inside branches
- Catches type errors at compile time
- Makes runtime checks and static types agree
AI Mentor Explanation
A type guard is like a fielding review that confirms exactly how a batter was out before the scorer records it. Once the check proves it was a catch, the system safely fills in bowler and fielder fields — details that only make sense once that specific dismissal type is confirmed.
Step-by-Step Explanation
Step 1
Use typeof for primitives
Branch with 'typeof x === "string"' to narrow a union like 'string | number' to string in that block.
Step 2
Use instanceof for classes
Check 'x instanceof Date' to narrow to a class instance and access its methods safely.
Step 3
Use the in operator
Test 'if ("swim" in animal)' to narrow by the presence of a distinguishing property.
Step 4
Write a custom guard
Declare a function returning 'arg is Fish' so a true result narrows the argument for the compiler.
Step 5
Rely on narrowed types
Inside the guarded branch, call type-specific members without casts, since the compiler now knows the exact type.
What Interviewer Expects
- Knowing typeof, instanceof and in as guards
- Understanding type predicates (arg is Type)
- How narrowing works inside a branch
- Why guards beat unsafe assertions
- Applying guards to discriminated unions
Common Mistakes
- Using type assertions instead of real runtime checks
- Writing a custom guard without an 'is' predicate return type
- Assuming narrowing persists outside the guarded branch
- Using 'in' on a property both union members share
- Forgetting instanceof fails across some realm boundaries
Best Answer (HR Friendly)
“A type guard is a check that tells the code what kind of value it is dealing with, like confirming something is text before treating it as text. After the check, the code can safely use features that only that specific type has, avoiding errors.”
Code Example
// typeof guard narrows a union
function format(value: string | number): string {
if (typeof value === 'string') {
return value.toUpperCase(); // value is string here
}
return value.toFixed(2); // value is number here
}
// Custom type guard with a predicate
interface Fish { swim: () => void }
interface Bird { fly: () => void }
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function move(pet: Fish | Bird) {
if (isFish(pet)) {
pet.swim(); // narrowed to Fish
} else {
pet.fly(); // narrowed to Bird
}
}Follow-up Questions
- What is a type predicate and how does 'arg is Type' work?
- When would you use the 'in' operator over instanceof?
- How do discriminated unions simplify type guarding?
- Why is a type guard safer than a type assertion?
- What are the limitations of instanceof across execution contexts?
MCQ Practice
1. Which return type makes a function a custom type guard?
A type predicate of the form 'arg is Type' tells the compiler that a true result narrows the argument to that type.
2. Which operator narrows by checking for a property's presence?
The 'in' operator checks whether a property exists on an object, narrowing a union based on that presence.
3. Where is a narrowed type valid?
Narrowing applies within the branch where the guard holds; outside it, the type reverts to the broader union.
Flash Cards
What is a type guard? — An expression or function that narrows a value to a more specific type in a branch.
Name three built-in guards. — typeof, instanceof, and the 'in' operator (plus equality narrowing).
What signals a custom type guard? — A return type predicate like 'pet is Fish'.
Do assertions narrow safely? — No — assertions bypass checks; type guards use real runtime tests, so they are safe.