# Interfaces

Interfaces provide a powerful way to enforce the **structure** of variables. As you'll recall, TypeScript relies on duck typing, which makes interfaces a key way to enforce that an object (or class) adhere to a certain schema, or contract, as defined in the interface.

Consider the following example. The function `getRectangleArea` accepts anything so long as it contains `length` and `height` properties:

```typescript
interface Rectangle {
  length: number;
  height: number;
}

interface Cube {
  length: number;
  height: number;
  width: number;
}

const myRectangle: Rectangle = {
  length: 10,
  height: 10,
};

const myCube: Cube = {
  length: 10,
  height: 10,
  width: 2,
};

function getRectangleArea(rectangle: Rectangle) { /* do stuff */ }

getRectangleArea(myRectangle); // exact match is ideal
getRectangleArea(myCube); // extra properties are okay
getRectangleArea({ // Error: missing property `height`
  length: 10,
});
```

```typescript
interface Coords {
  latitude: number;
  longitude: number;
}

interface City {
  coords: Coords;
  name: string;
}

const userLocation: City = {
  coords: {
    latitude: 42.332,
    longitude: -73.324,
  },
  name: 'Montréal',
};
```

Because interfaces operate entirely at TypeScript compile time, they have *zero* impact at JS runtime.

The above example will simply transpile down to this JavaScript:

```javascript
var userCity = {
  coords: {
    latitude: 42.332,
    longitude: -73.324,
  },
  name: 'Montréal',
};
```

✨ ✨ ✨ ✨ ✨ ✨

## Interfaces are extensible

Interfaces in TypeScript can be extended if necessary. Simply re-declare the interface with additional properties. The interface's properties will then be merged with any that were previously declared.

For example:

```typescript
interface Squirrel {
  id: number;
  mutations: string[];
}

interface Squirrel {
  scientificName: string;
}
```

will effectively be enforced in the same way as

```typescript
interface Squirrel {
  id: number;
  mutations: string[];
  scientificName: string;
}
```

This can be useful, for example, if an external library defines an interface that needs to be augmented.

## Optional Properties

Not all properties of an interface may be required. These optional properties are popular when creating patterns like "option bags" where you pass an object to a function that only has a couple of properties filled in.

For example:

```typescript
interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  const newSquare = {
    color: 'white',
    area: 100
  };

  if (config.color) {
    newSquare.color = config.color;
  }

  if (config.width) {
    newSquare.area = config.width * config.width;
  }

  return newSquare;
}

let redSquare = createSquare({color: 'red'}); // {color: 'red', area: 100}
```

## Interfaces in classes

Interfaces can also be used to enforce classes to adhere to a certain contract.

For example:

```typescript
interface Dog {
  species: string;
  wagTail(speed: number): void;
}

class MyDog implements Dog {
  species = 'Canis familaris';
  isCool = true;
  wagTail(speed: number) { /* wag tail logic */};
}
```

To those unfamiliar, this might look like superfluous boilerplate. However, a lot of value is gained in the form of *trust* if you can make guarantees about what structure a class should have. In other words, `MyDog` may be more, but for the public API it must *at least* be a `Dog`.

## Interfaces vs. type aliases

> * Interfaces create a new name that is used everywhere. Type aliases don’t create a new name — for instance, error messages won’t use the alias name.
> * A second more important difference is that type aliases cannot be extended or implemented from (nor can they extend/implement other types). Because an ideal property of software is being open to extension, you should always use an interface over a type alias if possible.
> * On the other hand, if you can’t express some shape with an interface and you need to use a union or tuple type, type aliases are usually the way to go.
