Learn and use Composition in JavaScript and TypeScript
Tags: webdev, javascript, tutorial, beginners
Published: 2020-07-06 15:10:27

---
title: Learn and use Composition in JavaScript and TypeScript
published: true
description: This teaches you composition in JavaScript and TypeScript, both using classes and just objects.
tags: webdev, javascript, tutorial, beginners
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/plnf560j5smudw860bsw.jpg
---

Follow me on [Twitter](https://twitter.com/chris_noring), happy to take your suggestions on topics or improvements /Chris

What does the word composition mean? Let's start with the verb to *compose*. Looking up a dictionary you find a lot of references to composing music :) You will also find this definition:

> to be formed from various things

The above is probably closer to what I'm about to talk about next - Composition.

## Composition

The idea is to create something from other parts. Why would we want to do that? Well, it's easier to build something complex if it consists of many small parts that we understand. The other big reason is reusability. Bigger and more complex things can sometimes share parts they consist of, with other big and complex things. Ever heard of IKEA? ;)

There's more than one type of composition in programming, who knew? ;)

### Composition vs Inheritance

Let's quickly explain inheritance. The idea with inheritance is to *inherit* traits, fields as well as methods from a parent class. The class inheriting from a parent class is called a subclass. This inheritance makes it possible to treat a group of objects in the same way. Consider the below example:

```javascript
class Shape {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

class Movable extends Shape {
  move(dx, dy) {
    this.x += dx;
    this.y += dy;
  }
}

class Hero extends Movable {
  constructor(x, y) {
    super(x, y);
    this.name = 'hero';
  }
}

class Monster extends Movable {
  constructor(x, y) {
    super(x, y);
    this.name = 'monster';
  }
}

const movables = [new Hero(1,1), new Monster(2,2)];
movables.forEach(m => m.move(2, 3));
```

Above we can treat instances of `Hero` and `Monster` in the same way as they have a common ancestor `Movable` that allows them to be moved through the `move()` method. All this is based on a relationship principle `IS-A`. A `Hero` IS-A `Movable`, a `Monster` is a `Movable`.

There's been a lot of talks lately on how you should favor composition over inheritance, why is that? Let's look at some drawbacks with *inheritance*:

- **Liskov substitution principle is done wrong**, the idea behind this principle is the code should still work if I replace something with a common ancestor for something else, i.e replacing a `Hero` for a `Monster`, they are both of type `Movable`. In the above sample code that replacement should work. However, the above code represents the ideal case. Reality is much worse. In reality, there might exist large codebases where there are 20+ levels of inheritance, and inherited methods might not be implemented properly meaning that certain objects can't be replaced for one another. Consider the following code:

   ```javascript
   class NPC extends Movable {
     move(dx, dy) {
       console.log('I wont move')
     }
   }
   ```

   The above have broken the substitution principle. Now, our codebase is so small so we can spot it. In larger codebases, you might not be able to spot when this happens. Imagine this happens on inheritance level 3 and you have 20 levels of inheritance.

- **Lack of Flexibility**, a lot of the time you have a `HAS-A` relationship over `IS-A`. It's easier to think of different components doing various things rather than them having a commonality, a common ancestor. This may lead us to create a lot of extra classes and inheritance chains when a composition would have been more appropriate.

### Function composition

It's a mathematical term stating that states the following according to Wikipedia, *function composition is an operation that takes two functions f and g and produces a function h such that h(x) = g(f(x))*. Related to programming is when we apply at least two functions on something like so:

   ```javascript
   let list = [1,2,3];
   take(orderByAscending(list), 3)
   ```

   Above imagine that `list` is x, `f(x)` is `orderByAscending(list)` and `g(x)` is `take()` with `f(x)` as input parameter.

   The point is you have many operations applied one after another on a piece of data. Essentially you apply different parts to create a more complex algorithm that when invoked computes a more complex result. We won't spend so much time talking about this version of composition but know that it exists.

## Object Composition

This type of composition is about combining objects or other data types to create something more complex than what we started with. This can be accomplished in different ways depending on what language you have in front of you. In Java and C# you only have one way to create objects, by using a class. In other languages like JavaScript, you have objects that can be created in many ways and thereby you open up for different ways of composing.

### Object composition with Classes

Using classes is about a class referencing one or more other classes via instance variables. It describes a *has-a* association. Which means what exactly? A person has four limbs, a car may have 4 wheels, and so on. Think of these classes being referenced as parts or *composites* that gives you the ability to do something, a capability. Let's look at an example:

   ```javascript
   class SteeringWheel {
     steer(){}
   }

   class Engine {
     run(){}
   }

   class Car {
     constructor(steeringWheel, engine) {
       this.steeringWheel = steeringWheel;
       this.engine = engine;
      }

     steer() {
       this.steeringWheel.steer();
     }

     run() {
       this.engine.run();
     }
   }

   class Tractor {
     constructor(steeringWheel) {
       this.steeringWheel = steeringWheel;
     }

     steer() {
       this.steeringWheel.steer();
     }
   }
   ```

   What we are getting above is first a more complex class `Car` consisting of many parts `steeringWheel` and `engine` and through that, we gain the ability to *steer* and a vehicle that *runs*. We also get *reusability* as we can use the `SteeringWheel` and use it in a `Tractor`.

### Object composition without classes

JavaScript is a little different than C# and Java in that it can create objects in a number of ways like the following:

- **Object literal**, you can create an object by just typing it out like so:

   ```javascript
   let myObject { name: 'a name' }`
   ```

- `Object.create()`, you can just pass in an object and it will use that as template. Like this for example:

   ```javascript
   const template = {
     a: 1,
     print() { return this.a }
   }

   const test = Object.create(template);
   test.a = 2
   console.log(test.print()); // 2
   ```

- **Using `new`**. You can apply the `new` operator on both a class and a function, like so:

   ```javascript
   class Plane {
     constructor() {
       this.name = 'a plane'
     }
   }

   function AlsoAPlane() {
     this.name = 'a plane';
   }

   const plane = new Plane();
   console.log(plane.name); // a plane

   const anotherPlane = new AlsoAPlane();
   console.log(anotherPlane) // a plane
   ```

   There is a difference between the two approaches. You need to do a bit more work if you want *inheritance* to work for the functional approach among other things. For now, we are happy knowing that there are different ways to create objects using *new*.  

So how would we actually *compose*? To *compose* we need a way to express behavior. We don't need to use classes if we don't want to, but we can skip directly to objects instead. We can express our composites in the following way:

```javascript
const steer = {
  steer() {
    console.log(`steering ${this.name}`)
  }
}

const run = {
  run() {
    console.log(`${this.name} is running`)
  }
}

const fly = {
  fly() {
    console.log(`${this.name} is flying`)
  }
}
``` 

and *compose* them like so:

```javascript
const steerAndRun = { ...steer, ...run };
const flyingAndRunning = { ...run, ...fly };
```

Above we are using the *spread* operator to combine different properties from different classes and place them into one class. The resulting `steerAndRun` now contains `{ steer(){ ... }, run() { ... } }` and `flyingAndRunning` contains `{ fly(){...}, run() {...} }`.

Then using the method `createVehicle()` we create what we need like so:

```javascript
function createVehicle(name, behaviors) {
  return {
    name,
    ...behaviors
  }
}

const car = createVehicle('Car', steerAndRun)
car.steer();
car.run();

const crappyDelorean = createVehicle('Crappy Delorean', flyingAndRunning)
crappyDelorean.run();
crappyDelorean.fly();
```

The end result is two different objects with different capabilities.

### But I use TypeScript, what then

TypeScript makes heavy uses of classes and interfaces and that's a way to accomplish object composition using classes.

> Can I accomplish composition in a way similar to using the spread operator and objects?

Yes, yes you can. Hold on. We're going to use a concept called MixIns. Let's begin:

1. First, we need this construct:

   ```typescript
   type Constructor<T = {}> = new (...args: any[]) => T
   ```

   We use this construct to express that `Constructor` is something that can be instantiated.

1. Next, declare this function:

   ```typescript
   function Warrior<TBase extends Constructor>(Base: TBase) {
     return class extends Base {
       say: string = 'Attaaack';
       attack() { console.log("attacking...") }
     }
   }
   ```

   What's returned is a class inheriting from `Base`. `Base` is the input parameter to our function and is of type `TBase`, that uses the `Constructor` type we just created.

1. Let's define a class that will use the above function:

   ```typescript
   class Player {
     constructor( private name: string ) {}
   }
   ```

1. Now, invoke the `Warrior` function like so:

   ```typescript
   const WarriorPlayerType = Warrior(Player);
   const warrior = new WarriorPlayerType("Conan");
   console.log(warrior.say); // 'Attaaack'
   warrior.attack(); // 'attacking...'
   ```

1. We can keep composing by creating a new function that holds another behavior we might want:

   ```typescript
   function Wings<TBase extends Constructor>(Base: TBase) {
     return class extends Base {
       fly() { console.log("flying...") }
     }
   }
   ```

1. Let's use that on an existing composition

   ```typescript
   const WingsWarriorPlayerType = Wings(WarriorPlayerType);
   const flyingWarrior = new WingsWarriorPlayerType("Flying Conan");
   flyingWarrior.fly();
   ```

## Summary

This article described what composition is. Additionally, it talked about how *composition* is favored over inheritance. Then it covered that there are different ways to achieve composition. As a bonus, we also covered an approach you can use in TypeScript.

### Further reading

There are some great articles on this topic that I think you should read. Have a look at the following:

- [Composition in JavaScript](https://alligator.io/js/class-composition/#:~:text=A%20common%20composition%20pattern%20in,have%20an%20Animal%20and%20FlyingAnimal%20.)
- [Mixin classes in TypeScript](https://mariusschulz.com/blog/mixin-classes-in-typescript)