Unions & Intersections
Lesson Overview
Master type composition by combining types with Union and Intersection operators.
Unions & Intersections
In TypeScript, you can compose new types by combining existing ones. The two primary ways to do this are Union Types and Intersection Types.
Union Types (|)
A union type allows a value to be one of several types. Think of it as an “OR” relationship.
type ID = string | number;
function printId(id: ID) {
console.log(`Your ID is: ${id}`);
}
printId(101); // OK
printId("ABC"); // OK
Narrowing
When working with union types, you often need to narrow the type to perform type-specific operations.
function formatId(id: string | number) {
if (typeof id === "string") {
return id.toUpperCase(); // In this block, id is 'string'
}
return id.toFixed(2); // In this block, id is 'number'
}
Intersection Types (&)
An intersection type combines multiple types into one. The new type will have all the properties of every type in the intersection. Think of it as an “AND” relationship.
interface ErrorHandling {
success: boolean;
error?: { message: string };
}
interface ArtData {
title: string;
artist: string;
}
type ArtResponse = ArtData & ErrorHandling;
const response: ArtResponse = {
title: "The Starry Night",
artist: "Vincent van Gogh",
success: true
};
Discriminated Unions
A common pattern in TypeScript is to use a “tag” or “discriminant” property to distinguish between different types in a union.
interface Circle {
kind: "circle";
radius: number;
}
interface Square {
kind: "square";
sideLength: number;
}
type Shape = Circle | Square;
function getArea(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.sideLength ** 2;
}
}
This pattern is extremely helpful for handling complex state (like API states: Loading, Success, Error) in a type-safe way.