Unions and literals
| string | number | |
| Narrow with typeof | |
| Literal types | |
| Enums vs union of literals |
string | number
A union type allows a short list of alternatives separated by a vertical bar. The value below may be text or a number, but nothing else:
let id: string | number = "abc";
id = 42;
console.log(id);
42
Both assignments compile because both types belong to the union. Storing a boolean would fail, since it appears in neither alternative.
Narrow with typeof
Code can only use the members shared by every alternative until it checks which one arrived. A typeof check narrows the union, unlocking the methods of that branch:
function format(id: string | number): string {
if (typeof id === "string") {
return id.toUpperCase();
}
return String(id);
}
console.log(format("abc"));
ABC
Inside the if branch, id is proven to be a string, so toUpperCase is safe. Past the branch only the number case remains, and String turns it into text.
Literal types
A literal type pins a value to exact choices instead of a whole type. The direction below can only ever be one of two texts:
let direction: "up" | "down" = "up";
console.log(direction);
up
Any typo such as upward fails the compile at once. Literals shine for modes, states, and options where the valid set is small and fixed.
Enums vs union of literals
An enum also names a fixed set, but it creates a runtime object while a literal union vanishes after compile. Prefer the lighter union unless you need the extra features of an enum:
enum Role { Admin, User }
const me: Role = Role.Admin;
console.log(me === Role.Admin);
true
The check prints true because me holds the Admin member. For plain string choices the union form from the previous section stays simpler and easier to combine with other types.
Next: Function types
Article author: Arthur Isaev