Union of types
What is a union type
A union type is a type that can be one of several specified variants.
In TypeScript, unions are created with the vertical bar |:
let value: string | number;This means:
valuecan be either a string or a number, but nothing else.
Example 1. The simplest union
let id: string | number;
id = 42; // OK
id = "42"; // OK
id = true; // ErrorThis way you restrict the set of allowed types while still keeping flexibility.
Example 2. Unions in function parameters
function printId(id: string | number) {
console.log("ID:", id);
}
printId(123); // OK
printId("abc"); // OKThe function accepts either a string or a number, but nothing else.
Example 3. Not all methods are available with a union
When TypeScript cannot precisely determine the type at runtime, it only allows methods common to all the types.
function printId(id: string | number) {
console.log(id.length); // Error - number has no .length
}Solution: narrow the type (type narrowing):
function printId(id: string | number) {
if (typeof id === "string") {
console.log("String length:", id.length);
} else {
console.log("Number:", id.toFixed(2));
}
}After the
typeofcheck, TypeScript "understands" which concrete type is being used.
Example 4. Unions inside objects
You can combine different object shapes:
type User = { name: string; age: number };
type Admin = { name: string; permissions: string[] };
type Person = User | Admin;
const user1: Person = { name: "Tim", age: 25 }; // OK
const user2: Person = { name: "Alex", permissions: [] }; // OK
const user3: Person = { name: "Bob" }; // Error: age or permissions is requiredExample 5. Using it in a switch (discriminated unions)
TypeScript works especially well with unions if you add a discriminant: a common field for telling the variants apart.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.side ** 2;
}
}
area({ kind: "circle", radius: 10 }); // OKThis is called a discriminated union, one of the most powerful patterns in TS.
Example 6. Union of literal types
You can create restricted sets of values:
type Direction = "up" | "down" | "left" | "right";
let move: Direction;
move = "up"; // OK
move = "down"; // OK
move = "forward"; // ErrorVery convenient for statuses, roles, modes, and so on.
Example 7. Unions with null and undefined
Typical examples are variables that may be undefined:
let username: string | null = null;
function printName(name: string | undefined) {
if (name) {
console.log(name.toUpperCase());
}
}Such unions help TypeScript protect the code from "Cannot read property of null" errors.
Example 8. Unions with type aliases and interfaces
type Status = "loading" | "success" | "error";
type Response = { status: Status; data?: string };
function handleResponse(res: Response) {
if (res.status === "success") {
console.log(res.data);
}
}Union vs Intersection (| vs &)
| Operator | Name | Example | Meaning |
|---|---|---|---|
| | Union | A | B | an object that is either A or B |
& | Intersection | A & B | an object that is both A and B at once |
Example of the difference:
type Dog = { bark: () => void };
type Cat = { meow: () => void };
type PetUnion = Dog | Cat; // either a dog or a cat
type PetBoth = Dog & Cat; // both at once (a creature that can bark and meow)Summary
| Concept | Example |
|---|---|
| Simple union | string | number |
| Union of objects | {a: number} | {b: string} |
| Literal unions | "on" | "off" |
| Discriminated union | { kind: "circle" } | { kind: "square" } |
| Union with null/undefined | string | null |
Simple definition:
Union (
|) is "OR" for types.A variable can be one of several types, and TypeScript requires you to explicitly state which one is being used when you work with it.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.