Type Predicate / Type Guards - for convincing compiler of typescript
is - “type predicate”. to use for type guards. type guard: any expression used to narrow a type.
tell the compiler that this function returns a particular type when used anywhere, but only if this function returns true. if it returns false, the compiler doesn’t learn anything about its type
a normal boolean-returning function does not act as a type guard.
// Type-guarding function that will convince the compiler
// that if isThing(somethingHere) //=> true, then
// somethingHere is indeed a `thing`, type-wise.
function isThing(whatsit: thing | undefined): whatsit is thing {
return whatsit !== undefined;
}
// NOT a type-guarding function (because it only returns a boolean)
function unsureIfThing(whatsit: thing | undefined): boolean {
return whatsit !== undefined;
}
// using `unknown` is recommended, but `any` also works.
function isNumber(n: unknown): n is number {
return typeof n === 'number';
}
This is useful, say, in cases where you have a mixed array and you need it to filter down to a single-type array.
The type predicate only applies to the function itself - you cannot wrap a type-guard function in another function. This includes arrow functions, as they are technically a wrapping function!
=== is a type guard. this operator comes with JS. Array.isArray() is a type guard. this comes from TypeScript. isNumber is a type guard (from above example). we define these ourselves using the n is nubmer type predicate. turns the function into a type guard, rather than a standard boolean-returning function.