StructuralTypeScriptverifiedVerified

Composite Pattern in TypeScript

Composes objects into tree structures to represent part-whole hierarchies, letting clients treat individual objects and compositions uniformly.

How to Implement the Composite Pattern in TypeScript

1Step 1: Define the component interface for uniform treatment

interface Component {
  operation(): string;
  add?(c: Component): void;
  remove?(c: Component): void;
  isComposite(): boolean;
}

2Step 2: Implement Leaf and Composite node types

class Leaf implements Component {
  constructor(private name: string) {}
  operation(): string { return `Leaf(${this.name})`; }
  isComposite(): boolean { return false; }
}

class Composite implements Component {
  private children: Component[] = [];

  add(c: Component): void { this.children.push(c); }
  remove(c: Component): void {
    this.children = this.children.filter((ch) => ch !== c);
  }
  isComposite(): boolean { return true; }

  operation(): string {
    const results = this.children.map((c) => c.operation());
    return `Branch(${results.join("+")})`;
  }
}

3Step 3: Build a tree and traverse it uniformly

// Build tree:  Root → [Branch(Leaf1+Leaf2), Leaf3]
const tree = new Composite();
const branch = new Composite();
branch.add(new Leaf("1"));
branch.add(new Leaf("2"));
tree.add(branch);
tree.add(new Leaf("3"));

console.log(tree.operation());
// Branch(Branch(Leaf(1)+Leaf(2))+Leaf(3))

Composite Pattern Architecture

hourglass_empty

Rendering diagram...

lightbulb

Composite Pattern in the Real World

A company’s org chart is a composite structure. An individual employee (leaf) has a salary and a name. A department (composite) also has a name and a budget—calculated by summing the salaries of all its members, which may themselves be other departments. HR can call ‘get budget’ on the CEO’s node and the entire tree is summed recursively.