Type Predicates (is)
Teaching custom functions how to narrow types.
The extraction problem
In the previous concept, we saw that extracting a type guard (typeof val === "string") into a helper function breaks TypeScript's control flow analysis. A function that returns a boolean just means 'true or false'; it doesn't mean 'this specific variable is a string'.
A Type Predicate is a special return type that tells the compiler: 'If this function returns true, the argument passed to it is definitely this specific type'.
Reusable type guards
When checking for complex shapes (like validating if an API response matches a specific interface), the check can be dozens of lines long.
Type predicates allow you to encapsulate that ugly logic into a clean, reusable helper function without losing type safety.
The 'is' keyword
You define a type predicate by replacing the boolean return type with parameterName is Type.
typescript
// Without predicate: returns boolean
// With predicate: returns val is string
function isString(val: any): val is string {
return typeof val === "string";
}
if (isString(id)) {
// TS now knows id is a string!
id.toUpperCase();
}
Try it
Watch how changing a return type from boolean to val is string instantly fixes the compiler error inside the if-block.
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- A regular function returning
booleancannot narrow a type in anifblock. - A Type Predicate (
val is string) tells the compiler to narrow the type if it returns true. - TypeScript blindly trusts type predicates; if your logic is wrong, your app will crash.
- Use them only for complex validations you need to reuse.
Done with this concept?
Mark it complete to track your progress. No login needed.