Typescript type guards
Narrowing
-
Type Guards are a form to narrow a type, i.e. making the type more precise.
- in
let foo = "hello" as string
,"hello" extends string
- in
-
Read this article from the typescript docs.
A type guard is some expression that performs a runtime check that guarantees the type in some scope.
Different type guards
const bar: {
foo?: string[];
}
// JavaScript
if (bar.foo !== undefined) {
const myLength = foo.length;
}
// Built-in TypeScript type-guard
if (typeof bar.foo !== "undefined") {
const myLength = foo.length
}
Using the in
operator does not always work well (see this SO question):
if ('field' in Object) {
// ...
}
Different kinds to set up type guards.
Custom (user-defined) type guards
User-defined type guard
A user-defined type guard returns a type predicate of the form “parameterName” is
“Type”. It’s a boolean value describing whether the parameter “parameterName” is indeed type “Type”.
Example from this blog article about custom type guards:
const isCar = (variableToCheck: any): variableToCheck is Car =>
(variableToCheck as Car).turnSteeringWheel !== undefined;
Analogous from the TS Docs:
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
Type guards with generics:
Example 1 taken from here:
function isNotNullish<T>(value: T): value is NonNullable<T> { // (A)
return value !== undefined && value !== null;
}
With a generic
export const isOfType = <T>(
varToBeChecked: any,
propertyToCheckFor: keyof T
): varToBeChecked is T =>
(varToBeChecked as T)[propertyToCheckFor] !== undefined;
// use it as:
if (isOfType<Car>(vehicle, 'turnSteeringWheel')) {
// ...
}
Discuss on Twitter ● Improve this article: Edit on GitHub