patterntypescriptnoneModerate
Type Predicates (is keyword) for Custom Type Guards
Viewed 0 times
TypeScript 1.6+
type predicateis keywordtype guardnarrowingfilter type
Problem
Functions that check a value's type return 'boolean', so TypeScript doesn't narrow the type inside the calling code's if block.
Solution
Use a type predicate return type ('param is Type') to inform TypeScript that a true return means the parameter is the specified type.
interface Cat { meow(): void; }
interface Dog { bark(): void; }
// Without predicate — no narrowing
function isCat(animal: Cat | Dog): boolean {
return 'meow' in animal;
}
// With predicate — narrows correctly
function isCat(animal: Cat | Dog): animal is Cat {
return 'meow' in animal;
}
function makeNoise(animal: Cat | Dog) {
if (isCat(animal)) {
animal.meow(); // TypeScript knows it's Cat
} else {
animal.bark(); // TypeScript knows it's Dog
}
}
// Filtering arrays with type predicates
const values: (string | null)[] = ['a', null, 'b'];
const strings = values.filter((v): v is string => v !== null);
// strings: string[] — not (string | null)[]Why
TypeScript's control flow analysis only narrows based on built-in checks (typeof, instanceof) or type predicates. A predicate annotation tells the compiler to trust the function's boolean return as a type guarantee.
Gotchas
- TypeScript does NOT verify that your predicate implementation is correct — a lying predicate causes unsound types.
- Predicates only narrow in the positive branch; the negative branch narrows to the remainder of the union.
- Array.filter with a predicate requires the syntax '(v): v is Type => ...' not a separate function reference.
Revisions (0)
No revisions yet.