type vs interface in TypeScript
Tags: typescript, javascript, beginners, webdev
Published: 2021-04-09 19:10:17

When I first started working with TypeScript, I quickly found myself questioning the use of `type` and `interface` in regards to providing type safety to my code. What is the difference between the two? When should I use one over the other? I decided it was time to get some answers.

After a bit of research, I realized that the two are more similar today than they have ever been. However, there are still some differences that are worth mentioning. Let’s talk about it!

### types and interfaces at a high level

Before we take a look at the similarities and differences between a `type` and an `interface`, let’s first get a good mental model of what the two were intended to achieve in the first place.

The `type` keyword in TypeScript is a way for you to provide type aliases to your variables, objects, and functions. These aliases essentially _describe_ what your data is going to look like. You can describe what your data is going to look like by using the core types (e.g. `string`, `number`, `boolean` etc.) or by creating your own custom types. Let’s take a look at a few examples.

![1_MKAKdf6Gco0bcRhNr3pgjg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ehj9d5iv6ln8cj3m5er.png)
 
The `interface` keyword in TypeScript on the other hand is a way for you to describe **only** what your objects are going to look like. Let’s see an example of `interface`.

![1_hSlmeCXEy1x37EZ9E9smLQ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67zhfletiltbgvs5op0g.png)

Right off the bat, you might think that the `type` keyword is the more flexible choice of the two when it comes to type safety. Hold that thought. Let’s take a look now at how the two are similar.

### Similarities

Let’s say I wanted to provide some type safety for an object, one of the most common use cases for using a `type` or an `interface`. Turns out they both work pretty much the same, and the syntax is almost identical.

![1_TPjtC18Ro3IhSSro3ZXoYw](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/44iatgimtabmszm93vhn.png)

What if I wanted to combine object properties from one `type` or `interface` into another? We can do that too for both.

![1_ARdjVoUQbBugTD8MlvenrA](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10m7jy8j3dapyxso11on.png)

![1_yNQhRWm2m2F8esP1HPw1Yg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jwguegx24ggi9dlavfmk.png) _I personally prefer the extends syntax as it feels a bit more natural to me._

Want to provide some type safety to your functions? This is also possible with both a `type` and an `interface`.

![1_B1WDG4pKhygWDnPN8vCCEA](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7gx5733qewnx6pmfwvob.png) _I personally prefer using a type here since it reads a bit cleaner, but totally up to you!_

A quick note about the above. Earlier I mentioned that an interface can **only** describe what an object is going to look like, yet here I am describing what a function is going to look like with an `interface`. The reason this is possible is because a function technically _is_ an object under the hood.

Finally, if you wanted to create a class that adheres to a certain type safety contract provided by a `type` or an `interface`, you would be able to do so just fine with both.

![1_0FTHZgh-R80TUJ355AwURA](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9zf0gacwfbvrqkz811yv.png)

That covers most of the similarities of `type` and `interface`, let’s now take a look at the differences.

### Differences

Starting with `type`, there are a few things that are possible that you wouldn’t be able to do with an `interface`. For example, If you wanted to setup a type alias for just a single core type (e.g. string, number, boolean etc.), this is something that is possible with `type` but not with `interface`.

![1_9msX1PR0rC_REWxd3eouAw](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/op7uwnpwny4wsw85yfh0.png)

Another possibility with `type` is that you are able to create a bit more custom type aliases by using unions.

![1_QlcaARr_2JgnLPry7FEsoQ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/balanxh1crdkuimpg39j.png)

This pretty much sums up the unique offerings of `type`. While there may be some more advance features that `type` offers that I missed, this should cover the most common use cases.

Moving on to `interface`, there is a unique feature called “declaration merging” that you aren’t able to do with a `type`.

![1_pbV0jRO22ETpb0-_obqmBw](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0zhxxxvuqq52hdjuap1.png)

### Wrapping up

To summarize, both `type` and `interface` provide some nice type safety options for you to choose from depending on your needs. When it comes to describing object shapes which is the majority of my use cases, I prefer to go with an `interface`. I personally like that an `interface` was designed specifically with this purpose in mind, and is very intentional about it.

However anytime I need to provide type safety for a function, or need a bit more customization for a type alias such as the case with unions, I prefer to go with `type`. Both are lovely options for providing type safety, and you really can’t go wrong with using either one!