Lesson 8 of 15

Type Narrowing

Type Narrowing

Building on Union Types: In the previous lesson you wrote typeof checks to distinguish string | number in describe(). That was already narrowing in action! Here we will name the concept and explore more narrowing techniques.

When you have a union type, TypeScript does not know which specific type you have. Narrowing uses runtime checks to determine the actual type, letting TypeScript then give you the correct methods:

function process(val: string | number): string {
    if (typeof val === "string") {
        // TypeScript knows val is string here
        return val.toUpperCase();
    } else {
        // TypeScript knows val is number here
        return val.toFixed(2);
    }
}

typeof Narrowing

typeof narrows primitive types:

typeof val === "string"   // narrows to string
typeof val === "number"   // narrows to number
typeof val === "boolean"  // narrows to boolean

in Narrowing

The in operator checks if an object has a property:

interface Cat { meow(): void; }
interface Dog { bark(): void; }

function makeSound(animal: Cat | Dog): void {
    if ("meow" in animal) {
        animal.meow();  // TypeScript knows it's a Cat
    } else {
        animal.bark();  // TypeScript knows it's a Dog
    }
}

Your Task

Write function format(val: string | number): string that:

  • If val is a string: returns it in uppercase
  • If val is a number: returns it with 2 decimal places (use toFixed(2))
TypeScript loading...
Loading...
Click "Run" to execute your code.