TypeScript follows your ifs
Inside if (typeof id === "string"), TypeScript knows id is a string. This is narrowing: ordinary JavaScript checks that shrink a union to the type you've proved.
Ways to narrow
function describe(value: string | number | string[] | null) {
if (value === null) return "nothing";
if (typeof value === "number") return value.toFixed(1);
if (Array.isArray(value)) return value.join(", ");
return value.toUpperCase();
}
console.log(describe(null), describe(3), describe(["a", "b"]), describe("hi"));
type Cat = { meow(): string };
type Dog = { bark(): string };
function speak(pet: Cat | Dog) {
return "meow" in pet ? pet.meow() : pet.bark();
}
console.log(speak({ bark: () => "Woof" }));instanceof narrows too: if (err instanceof Error) err.message.