TypeScript Union Types and Narrowing: typeof, in and Array.isArray
November 6, 2026
Welcome to episode 16 of TypeScript from Zero, a series for complete beginners (no JavaScript needed). Welcome back to TypeScript from zero! Today: union types. Sometimes a value can be one of several types. We stay in the shop project, with a new file called unions.ts. Every code block below is the code from the video, ready to copy; run each file to see the output.
- All episodes are in the TypeScript from Zero playlist.
- Versions used: Node.js 26.13.0, npm 11.20.0, TypeScript 7.0.2.
Setup
We start in the terminal and open the project in VS Code:
$ touch src/unions.ts1. Union
A vertical bar between two types means: this or that. The variable id can hold a string or a number. We start with the number one hundred and one, and later we store a text.
let id: string | number = 101;
console.log(id);
id = "A-7";
console.log(id);$ node src/unions.ts2. typeof
But with a union, we can only use what both types have. To use more, we narrow the type. The word typeof tells us what we have. Inside the if block, TypeScript knows that value is a string, and after it, a number.
function describe(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
console.log(describe("hi"));
console.log(describe(3.14159));$ node src/unions.ts3. in
The word in checks if an object has a property. A cat can meow, a dog can bark. If the pet has meow, it must be a cat, and otherwise TypeScript knows it is a dog.
type Cat = { meow: () => void };
type Dog = { bark: () => void };
function speak(pet: Cat | Dog) {
if ("meow" in pet) {
pet.meow();
} else {
pet.bark();
}
}
speak({ meow: () => console.log("Meow") });$ node src/unions.ts4. isArray
And Array dot is array tells us if something is a list. Here the input is one text, or a list of texts. For a list we return its length, and for a single text we return one.
function count(x: string | string[]) {
if (Array.isArray(x)) {
return x.length;
}
return 1;
}
console.log(count(["a", "b"]));
console.log(count("a"));$ node src/unions.ts5. Mistake
Now the mistake. A function takes a string or a number, and calls to upper case without checking. With text it works, but when we pass the number five, Node crashes: value dot to upper case is not a function.
function bad(value: string | number) {
return value.toUpperCase();
}
console.log(bad(5));$ node src/unions.ts6. tsc
tsc would have warned us. Property to upper case does not exist on type string or number. The code is TS2339. A number has no such method, so the union is not safe.
$ npx tsc --noEmit7. Fix
The fix: turn the value into a string first. Now both cases work, and tsc is quiet.
$ node src/unions.ts$ npx tsc --noEmitRecap
Today: union types with a vertical bar, narrowing with typeof, in, and Array dot is array, and the error when we skip the check. Next episode: null and undefined.