Union Types
A union type allows a value to be one of several types. Use the pipe (|) operator to combine types.
Example
// Union type
type StringOrNumber = string | number;
function display(value: StringOrNumber) {
if (typeof value === "string") {
console.log(value.toUpperCase());
} else {
console.log(value.toFixed(2));
}
}
display("hello"); // "HELLO"
display(3.14); // "3.14"
// Literal union types
type Status = "active" | "inactive" | "pending";
let userStatus: Status = "active"; Discriminated Unions
Discriminated unions use a common property to distinguish between variants. This is a powerful pattern for modeling data.
Example
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number }
| { kind: "rectangle"; width: number; height: number };
function area(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.side ** 2;
case "rectangle":
return shape.width * shape.height;
}
}
console.log(area({ kind: "circle", radius: 5 })); // 78.54 Intersection Types
Intersection types combine multiple types into one. A value must satisfy all combined types.
Example
type HasName = { name: string };
type HasAge = { age: number };
type HasEmail = { email: string };
// Intersection: must have ALL properties
type Person = HasName & HasAge;
type Contact = Person & HasEmail;
const contact: Contact = {
name: "Alice",
age: 25,
email: "alice@example.com"
};
// Practical: extending API responses
type ApiResponse<T> = {
status: number;
timestamp: string;
} & T;
type UserResponse = ApiResponse<{ user: { name: string } }>; 