Wikipedia define adapter pattern as

In software engineering, the adapter pattern is a software design pattern that allows the interface of an existing class to be used as another interface. It is often used to make existing classes work with others without modifying their source code.

Lets see this in action. Lets suppose we are building Duck simulator

interface Duck {
  quack();
  fly();
}

We have a duck interface which consists of two methods.

class MallardDuck implements Duck {
  display() {
    // displays mallard duck
  }

  fly() {
    // implement swim behaviour
  }

  quack() {
    // implements quack behaviour
  }
}

We have MallardDuck which implements the Duck interface.

class DuckSimulator {
  constructor() {
    const duck = new MallardDuck();
    this.quackAndFly(duck);
  }

  quackAndFly(duck: Duck) {
    duck.quack();
    duck.fly();
  }
}

Inside the DuckSimulator we create a new Duck instance of MallardDuck and assign it to the duck. So far everything is working fine. If we call the quackAndFly method of the DuckSimulator it will execute the fly and quack method of MallardDuck

Now lets suppose we want to add Turkey into our DuckSimulator.

interface Turkey {
  gobble();
  fly();
}

The Turkey interface is slightly different from the Duck's interface so we can not add it directly to our DuckSimulator.

class WildTurkey implements Turkey {
  gobble() {
    console.log("gobble!");
  }

  fly() {
    console.log("Fly");
  }
}

We can not use Turkey in DuckSimulator because DuckSimulator expects the type objects to be of type Duck and the interface for Duck and Turkey have differences due to which it can not be used.

To overcome this we can use a Adapter. An Adapter acts as a bridge between Duck and Turkey objects.

We will create a new class called TurkeyAdapter. This class will act as an adapter between Duck and Turkey

This class will implement the Duck interface so we can directly plug it into the Duck class. Inside the implementation of Duck’s interface method, we will call the corresponding methods of the Turkey class. Lets see an example so its more concrete

class TurkeyAdapter implements Duck {
  constructor(private turkey: Turkey) {}

  quack() {
    this.turkey.gobble();
  }

  fly() {
    this.turkey.fly();
  }
}

Now we can use this inside the DuckSimulator

class DuckSimulator {
  constructor() {
    const duck = new MallardDuck();
    this.quackAndFly(duck);
    const wildTurkey = new TurkeyAdapter(new WildTurkey());
    this.quackAndFly(wildTurkey);
  }

  quackAndFly(duck: Duck) {
    duck.quack();
    duck.fly();
  }
}