# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://shopify-1.gitbook.io/typescript/beginner/interfaces.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
