Built-in, Custom, and Runtime Type Safety - Textnotes

Built-in, Custom, and Runtime Type Safety


Learn how to use type guards in TypeScript to ensure runtime type safety. This module explains built-in type guards, custom type guards, and techniques to enforce type safety at runtime with practical examples.

1. Built-in Type Guards

TypeScript provides built-in type guards to narrow types during runtime checks. Common guards include typeof, instanceof, and in.

Example: typeof


function formatValue(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}

Example: instanceof


class Dog {
bark() { console.log("Bark"); }
}

class Cat {
meow() { console.log("Meow"); }
}

function makeSound(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}

Example: in Operator


interface Admin {
name: string;
privileges: string[];
}

interface User {
name: string;
}

function printInfo(person: Admin | User) {
if ("privileges" in person) {
console.log(person.privileges);
} else {
console.log(person.name);
}
}

2. Custom Type Guards

Custom type guards allow developers to define their own type-checking functions. They return a boolean and use the x is Type syntax to inform TypeScript of the type.

Example


interface Fish {
swim: () => void;
}

interface Bird {
fly: () => void;
}

function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}

function moveAnimal(pet: Fish | Bird) {
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
}

Custom type guards are particularly useful when discriminating complex union types.

3. Runtime Type Safety

Type guards ensure safe operations at runtime by narrowing union types and preventing invalid property access.

Example


function process(input: string | number) {
if (typeof input === "string") {
console.log(input.trim());
} else {
console.log(input.toFixed(2));
}
}

Benefits

  1. Prevents runtime errors caused by invalid operations
  2. Improves code readability and maintainability
  3. Provides compile-time type safety with dynamic runtime checks

Conclusion

Type guards in TypeScript provide essential mechanisms for ensuring runtime type safety. Built-in guards, custom guards, and proper runtime checks allow developers to work confidently with union types and complex type structures, making applications safer and more robust.