# Interfaces in TypeScript

Source: https://tpiros.dev/blog/interfaces-in-typescript

Interfaces let you define the shape of an entity. You can say: "a Person must have a name and an age." And since we're in TypeScript, you can also nail down the types: name must be a string, age must be a number.

> TypeScript's type-checking focuses on the shape of values. That's called duck typing. Without it, if you wanted to call a method on an object, the system would have to verify the object's exact type. Consider a `Car` object where you want to call `startEngine`. Without duck typing, you'd need to ensure only `Car` objects get passed in. With duck typing, you can accept any object. As long as it has a `startEngine` method, the code runs.

Interfaces enforce rules on the objects we create.

Let's build one:

```typescript
interface IWarrior {
  name: string;
  health: number;
}
```

We've defined an `IWarrior` interface. Any object implementing it must contain `name` and `health` properties. Let's put it to work:

```typescript
let myWarrior: IWarrior = {
  name: 'John the Nomad',
  health: 100,
};
```

Using Visual Studio Code, you'll spot errors immediately. Create a variable, assign the `IWarrior` interface, then try adding a property that's not in the interface:

```typescript
let myWarrior: IWarrior = {
  name: 'John the Nomad',
  health: 100,
  weapon: 'sword', // Object literal may only specify known properties, and 'weapon' does not exist in type 'IWarrior'.
};
```

You can define optional properties too. Just stick a question mark after the property name:

```typescript
interface IWarrior {
  name: string;
  health: number;
  weapon?: string;
}

let myWarrior: IWarrior = {
  name: 'John the Nomad',
  health: 100,
  weapon: 'sword', // this property is now optional
};
```

Can you make a property read-only from within the interface itself? Yes. TypeScript lets you mark interface properties as read-only:

```typescript
interface IWarrior {
  name: string;
  readonly health: number;
  weapon?: string;
}

let myWarrior: IWarrior = {
  name: 'John the Nomad',
  health: 100,
  weapon: 'sword',
};

myWarrior.health = 80; //Cannot assign to 'health' because it is a constant or a read-only property.
```

Interfaces are a solid way to declare entities and their properties. They let developers enforce these shapes across the rest of the codebase.
