In TypeScript, Union and Intersection types provide the flexibility to combine types in two distinct ways: one allows for a choice between types, while the other merges them together.
Union Types (|)
A Union Type allows a variable to be one of multiple types. It is commonly used when a function needs to handle different kinds of inputs (e.g., a search ID that could be a string or a number).
let data: string | number;
data = "Hello"; // ✅ Valid
data = 42; // ✅ Valid
data = true; // ❌ Error: Type 'boolean' is not assignable to 'string | number'.
Type Narrowing
Because a union type variable could be one of several types, TypeScript won't let you perform operations specific to one type without a check. You use the typeof operator to narrow the type so you can handle each case safely.
function formatInput(input: string | number) {
if (typeof input === "string") {
// TypeScript knows 'input' is a string here
return input.toUpperCase();
} else {
// TypeScript knows 'input' must be a number here
return input.toFixed(2);
}
}
console.log(formatInput("hello")); // "HELLO"
console.log(formatInput(3.14159)); // "3.14"
Intersection Types (&)
An Intersection Type combines multiple types into one. Instead of choosing between them, the resulting type must have all properties from all combined types. This is essentially a way to "merge" existing types.
Example: Merging Objects
In the example below, the mgr object is required to satisfy both the Employee structure and the Manager structure.
type Employee = { name: string; id: number };
type Manager = { department: string };
// Combines both types into one
type ManagerEmployee = Employee & Manager;
const mgr: ManagerEmployee = {
name: "Ali",
id: 1,
department: "Engineering",
};
Intersecting Incompatible Types
Intersection types work well when merging object types, but intersecting incompatible primitive types — like string & number — produces the never type. This is TypeScript's way of representing something that is impossible: no value can be both a string and a number at the same time.
type Impossible = string & number;
// TypeScript resolves this as 'never' — no value can satisfy both types
You will encounter never in TypeScript when a type resolves to an impossible state. It is worth recognising so that when it appears in an error message, you understand what it means.
Quick Comparison
| Logic | Operator | Memory Aid |
|---|---|---|
| Union | | | "This OR That" |
| Intersection | & | "This AND That" |