My previous post showed with some short code snippets 5 useful TypeScript ticks. One of those tricks was a User-Defined Type Guard. Since this "trick" has attracted a lot of attention, I decided to write this short post to make this concept easier to understand.
What are Type Guards
A Type Guard reduces the type of object in a conditional block. The most known Type Guards are the famous typeof
and instanceof
operators.
Different Type Guards
typeof
-
instanceof
in
- Literal Type Guard
-
null
andundefined
withstrictNullChecks
- User-Defined Type Guards
Creating a User-Defined Type Guard
Unfortunately one can quickly feel the limits of the basic Type Guards when e.g. working with plain JavaScript objects.
Below an example of a user defined Type Guard.
interface IApple{
name: string;
color: string;
}
interface IBanana{
name: string;
size: number;
}
type Fruit = IApple | IBanana;
/** Custom Type Guard */
const isApple = (f: Fruit): f is IApple => {
return (f as IApple).color !== undefined
}
const apple: Fruit = {name: "Pink Pearl", color: "red"};
const banana: Fruit = {name: "Cavendish", size: 20};
console.log(isApple(apple)) // Logs true
console.log(isApple(banana)) // Logs false
f is IApple
is a type predicate. With this, instead of just returning a boolean, TypeScript will reduce the type to IApple
.
In the following code TypeScript will understand that inside the condition apple
is an IApple
.
if(isApple(apple)){
/** TS undestands that apple is an IApple */
console.log(apple.color); // Logs red
}
This is the big advantage of using User-Defined Type Guards. Be aware that a wrongly coded Type Guards can introduce major errors into your code.
Top comments (1)
Thanks for this post! I enjoyed it even if it’s almost ripped off the official documentation ☺️