Programming Fundamentals › Type Systems
Type Guard
A check that tells the type checker a value's specific type.
Also known as: user-defined type guard, narrowing
A type guard is a function that checks a value at runtime and tells the type checker what type it has. In TypeScript, the return type x is Something does this. Inside an if that uses the guard, the compiler narrows the value to that type.
function isString(value: unknown): value is string {
return typeof value === "string";
}
function shout(value: unknown): string {
if (isString(value)) {
return value.toUpperCase(); // value is string here
}
return "not text";
}
shout("hello"); // "HELLO"
shout(42); // "not text"
Without the guard, the compiler wouldn’t know value has a toUpperCase method, and the code wouldn’t compile. The guard does the runtime check and records the result for the compiler.
The trade-off is trust. The compiler accepts whatever the guard says, so a guard that checks too little, or the wrong thing, produces unsafe code that looks type-checked. The guard’s body is ordinary code, and TypeScript doesn’t verify that it matches the claim in the return type.
The classic mistake is writing a guard that only checks part of the shape, such as typeof value === "object", and then claiming value is User. Any object passes, and later code fails on a missing field. Check the properties the rest of the code relies on, or validate with a schema library so the check and the type come from one definition. For combining guarded types, see intersection types.