So far every variable had exactly one type: a string, a number, a boolean. But real programs are messier — a user ID might arrive as "abc-123" or as 42. TypeScript handles this with a union type: write the allowed types separated by | (read it as "or").
let id: string | number = "abc-123";
id = 42; // fine — number is part of the union
id = true; // error — boolean is NOT in the union
A string | number variable can hold either kind of value, and TypeScript tracks that for you.
The trap:
Here is where beginners get stuck. While a value's type is still the whole union, you may only use operations that are safe for every member. Strings have .length, numbers don't — so the compiler rejects this:
function describe(x: string | number): string {
return "length is " + x.length; // numbers have no .length!
}
error TS2339: Property 'length' does not exist on type 'string | number'.
Property 'length' does not exist on type 'number'.
Read the second line carefully — the compiler even names the guilty member: it's number that has no .length. You WILL see this error; it means "prove which type you have first".
Narrowing with typeof:
The proof is an ordinary if. The typeof operator returns the runtime type as a string ("string", "number", ...), and TypeScript understands the check: inside the branch, the union narrows to a single type.
if (typeof x === "string") {
// here x is a string — .length is allowed
} else {
// only number is left — x * 2 is allowed
}
Notice the else: no second check needed. Ruling out string leaves exactly one member, so TypeScript narrows x to number automatically.
Assignment
Follow the Coding Tutorial and write a function describe(x) where x is a string | number, returning a string:
- if
xis a string, return"string of length "plusx.length, - otherwise, return
"number doubled to "plusx * 2.
Then call it with "Algo" and with 21, printing each result with console.log, so both branches run. The exact expected output is:
string of length 4
number doubled to 42
Hint
Compare against the string "string": typeof x === "string". Writing typeof x === string (no quotes) is itself a type error.
Free plan: 30 tutor messages. PRO is unlimited.
