Types vs. Interfaces in Typescript
Tags: typescript, javascript
Published: 2021-05-09 07:00:52

 _Note: The term "Types" in this article is referring to the"`type`" aliases in Typescript_

According to the [official Typescript document](https://www.typescriptlang.org/): "TypeScript is an open-source language that builds on JavaScript, one of the world’s most used tools, by adding static type definitions." Implementing typescript on our project saves a lot of time in the long run. But as a developer, we should follow the best practices and standards when working with types in typescript. 
In this article, we will take a look at the differences between two types `type` aliases and `interface`. Many developers don't really know the real difference between these two. Having known the differences, we can implement these according to the best use case for us. 


## Origin
Interfaces are used to define data structures, for example, an Object's shape/structure.

Types are used to define the type of data, for example: Primitive, Union, Intersection, Tuple data types.


## Type Evaluation Time

There is a subtle key difference in the type evaluation period. Type evaluation on `type` aliases is _immediate_ while Type evaluation on the `interface` is _lazy_.


## Type Declaration Syntax

Even though both types and interfaces can be used in a similar way, their declaration syntax differs.

```typescript
type BulldogType = {
  name: string;
  height: number;
  weight: number;
}

interface BulldogInterface {
  name: string;
  height: number;
  weight: number;
} 
```


## Extends & Implements keyword

In Typescript, we can extend and implement types using the `interface`. This is not possible using the `type` aliases.

```typescript
interface Dog {
  breed: string;
}

interface Bulldog extends Dog {
  isCute: true;
}
```


## Intersection

We can combine multiple `types` and `interface` with the"`&`" keyword into a single `type`. But, we cannot combine them into a single `interface`.

```typescript
type Bulldog = { }
type GermanShepherd = {}

type DogBreeds = Bulldog & GermanShepherd; // valid

interface IBulldog {}
interface IGermanShepherd {}

type IDogBreeds = IBulldog & IGermanShepherd; // valid
  
```


## Unions

Union types allow us to create a new type that can have a value of one or a few more other types with the"`|`" keyword.
We can combine multiple `types` and `interface` with the union keyword into a single `type`. But, we cannot combine them into a single `interface`.

```typescript
type Bulldog = { }
type GermanShepherd = {}

type DogBreeds = Bulldog | GermanShepherd; // valid

interface IBulldog {}
interface IGermanShepherd {}

type IDogBreeds = IBulldog | IGermanShepherd; // valid
```


## Declaration merging

`interface` allows for declaration merging whilst `type` aliases don't. Typescript compiler intelligently merges two or more interfaces that share the same name into only one declaration.

```typescript
interface IBulldog {
 name: string;
}
interface IBulldog {
 weight: number;
}

const bruno: IBulldog = {
  name: "Bruno",
  weight: 22
}
```

But `type` aliases can't be changed once a type is created using the `type` alias. So, declaration merging isn't possible with the `type` aliases.

```typescript
type IBulldog = {
 name: string;
}
type IBulldog = {
 weight: number;
}

// Error: Duplicate identifier 'IBulldog'
```