Adapter Pattern - Interface Compatibility in TypeScript

Learn the Adapter pattern for making incompatible interfaces work together. TypeScript examples for legacy integration, API wrappers, and third-party libraries.

Structural

Detailed Explanation

Adapter Pattern

The Adapter pattern converts the interface of a class into another interface that clients expect. It allows classes that could not work together due to incompatible interfaces to collaborate.

Two Flavors

  1. Object Adapter (composition): The adapter holds a reference to the adaptee and delegates calls. This is the preferred approach in most languages.
  2. Class Adapter (inheritance): The adapter extends both the target interface and the adaptee class. This requires multiple inheritance and is rarely used in TypeScript.

Practical Example

// Old analytics library
class LegacyAnalytics {
  trackEvent(category: string, action: string, label: string) {
    return { category, action, label };
  }
}

// New interface your app expects
interface Analytics {
  track(event: { name: string; properties: Record<string, string> }): void;
}

// Adapter
class AnalyticsAdapter implements Analytics {
  constructor(private legacy: LegacyAnalytics) {}

  track(event: { name: string; properties: Record<string, string> }) {
    this.legacy.trackEvent(
      event.properties.category || "general",
      event.name,
      JSON.stringify(event.properties)
    );
  }
}

Adapter vs Facade

Both simplify interfaces, but for different reasons. An Adapter makes an existing interface match a target interface (same functionality, different shape). A Facade simplifies a complex subsystem by providing a new, simpler interface (reduced functionality, easier to use).

When to Use

Use Adapter when you need to integrate a third-party library that has a different interface from your codebase, when migrating from one API to another gradually, or when creating a consistent interface for multiple implementations that each have their own API.

Use Case

Adapter is essential when integrating third-party payment gateways (Stripe, PayPal) behind a uniform payment interface, wrapping legacy REST APIs to match modern GraphQL resolvers, converting between data formats (XML to JSON adapters), and creating database driver abstractions.

Try It — Design Pattern Reference

Open full tool