← Back to TypeScript Course | Chapter 16: Advanced Patterns | Lesson 2 of 7

Factory Pattern

The Factory Pattern moves object creation into a dedicated function or class. It is useful when the exact object type should be selected based on input without exposing construction details.

Factory Function

A factory function is the simplest form of this pattern — a typed function that takes some input and returns a fully constructed object, hiding the object's construction details behind a single call.

Example: Factory Function

typescript
interface User {
  name: string;
}
function createUser(name: string): User {
  return { name };
}
console.log(createUser("Ravi"));

Factory with Interface

A factory typed against an interface guarantees every object it produces satisfies that interface's shape, even if the factory internally creates several different concrete implementations behind the scenes.

Example: Factory with Interface

typescript
interface Shape {
  area(): number;
}
function createSquare(side: number): Shape {
  return { area: () => side * side };
}
console.log(createSquare(4).area());

Factory Class

A factory class groups related creation logic into methods, which is useful when constructing an object requires several steps or depends on shared internal state the factory itself maintains between calls.

Example: Factory Class

typescript
class WidgetFactory {
  private count = 0;
  create(name: string) {
    this.count++;
    return { id: this.count, name };
  }
}
const factory = new WidgetFactory();
console.log(factory.create("Button"));

Configuration-Based Creation

Configuration-based creation means the factory picks which concrete type to construct based on a passed-in option (like a type: circle | square field), centralizing that branching logic in one place instead of scattering it.

Example: Configuration-Based Creation

typescript
interface Shape { area(): number; }
function createShape(type: "circle" | "square", size: number): Shape {
  if (type === "circle") return { area: () => Math.PI * size * size };
  return { area: () => size * size };
}
console.log(createShape("circle", 2).area());

When to Use Factory

Reach for the factory pattern when object creation involves meaningful decision logic or setup steps — for a plain object with no real construction complexity, a factory adds indirection without adding value.

Example: When to Use Factory

typescript
interface Shape { area(): number; }
function createShape(type: "circle" | "square", size: number): Shape {
  return type === "circle"
    ? { area: () => Math.PI * size * size }
    : { area: () => size * size };
}
console.log(createShape("square", 3).area());
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.