T

Type Guards

Type guards narrow types at runtime, helping TypeScript understand which type you're working with.

Code

typescript
1// typeof type guard
2function padLeft(value: string | number, padding: string | number): string {
3 if (typeof padding === "number") {
4 return " ".repeat(padding) + value;
5 }
6 return padding + value;
7}
8
9console.log(padLeft("Hello", 4)); // " Hello"
10console.log(padLeft("Hello", ">>> ")); // ">>> Hello"
11
12// instanceof type guard
13class Dog {
14 bark(): void {
15 console.log("Woof!");
16 }
17}
18
19class Cat {
20 meow(): void {
21 console.log("Meow!");
22 }
23}
24
25function makeSound(animal: Dog | Cat): void {
26 if (animal instanceof Dog) {
27 animal.bark();
28 } else {
29 animal.meow();
30 }
31}
32
33// Custom type guard with "is" keyword
34interface Fish {
35 swim: () => void;
36}
37
38interface Bird {
39 fly: () => void;
40}
41
42function isFish(pet: Fish | Bird): pet is Fish {
43 return (pet as Fish).swim !== undefined;
44}
45
46function move(pet: Fish | Bird): void {
47 if (isFish(pet)) {
48 pet.swim();
49 } else {
50 pet.fly();
51 }
52}
53
54// in operator type guard
55interface Admin {
56 name: string;
57 privileges: string[];
58}
59
60interface Employee {
61 name: string;
62 startDate: Date;
63}
64
65function printInfo(person: Admin | Employee): void {
66 console.log(`Name: ${person.name}`);
67 if ("privileges" in person) {
68 console.log(`Privileges: ${person.privileges.join(", ")}`);
69 }
70 if ("startDate" in person) {
71 console.log(`Start Date: ${person.startDate.toDateString()}`);
72 }
73}
74
75const admin: Admin = { name: "Alice", privileges: ["create", "delete"] };
76printInfo(admin);

Run this example locally

$ npx ts-node types/type-guards.ts