Interface vs Type alias in TypeScript 2.7

People often ask me ( online, at work, in skatepark (nope 😂) ), what’s the difference between using type and interface for defining compile time types within TypeScript.

First thing I used to do, was pointing them to TypeScript handbook…

Unfortunately most of the time, they didn’t find the droids that they were looking for ( it’s hidden within Advanced Types section). Even if they found it, the information described there is obsolete ( described behaviour is for typescript@2.0.x ).

Good news everyone! You don’t have to look any further, This post is an up to date description/style-guide about when to use interface vs type alias.

What official documentation says:

“type aliases can act sort of like interfaces, however, there are some subtle differences.”

that’s correct !

What differences?

1. “One difference is, that 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.”

that’s incorrect ! (since TypeScript 2.1)

Let’s define compile time types for Point via interface and type alias and 2 implementation of getRectangleSquare function which will use both interface and type alias for parameter type annotation.

So errors are same for both:

2. “A second more important difference is that type aliases cannot be extended or implemented from”

Again, that’s incorrect!

We can extend an interface with type alias:

Or use type alias for implementing a Class constraint

Or use interface extended by an type for implementing a Class constraint

We can also combine both type alias and interface for implementing a Class constraint

3. “type aliases cannot extend/implement other types”

Again, that’s incorrect!

Well it’s partially correct but the formulation is miss leading 👀.

You can use interface or any other TypeScript valid type(which has shape of an Dictionary/JS Object, so non primitive types etc…) for type alias extension via intersection operator &

We can also leverage mapped types for various transforms of both interface and type alias.

Let’s make Shape and Perimeter optional via Partial mapped type:

Also weak type detection works correctly:

Hybrid Types with both type alias and interface

You might occasionally want to define an object that that acts as both a function and an object, with additional properties.

What we are talking here about, is defining a type for a function ( callable object ) and static properties on that function.

This pattern might be also seen, when interacting with 3rd-party JavaScript, to fully describe the shape of the type.

It works equally with type alias!

There is a very subtle difference though. You will get the particular shape type in IDE instead of reference to the Countertype.

What is usually a good idea/practice, is to dissect our hybrid definition in two parts:

  • callable object (function) type alias
  • static properties object shape

and final Counter type:

So what’s the difference between type alias and interface again 🤖?

1. you cannot use implements on an class with type alias if you use union operator within your type definition

This will trigger compile errors:

Which makes complete sense! A class blueprint, cannot implement one or another shape structure, so nothing surprising on this front.

Where type alias union usage makes sense and also works, is for object definition via object literal. So following is valid and will produce compile error, because our object has to define one of perimeter() or area() methods, or both:

2. you cannot use extends on an interface with type alias if you use union operator within your type definition

Again, similarly to class implementsusage, interface is a "static" blueprint — it cannot exists in one or another shape, so it cannot be extended by union type merge.

3. declaration merging doesn’t work with type alias

While declaration merging works with interfaces, it fails short with type aliases.

What I mean by declaration mergin?:

You can define same interface multiple times, and its definitions will merge into one:

This doesn’t work with type aliases, because type is an unique type entity ( for both global or module scope ):

Declaration merging via interfaces is very important, when we are writing 3rd party ambient type definitions for libraries that are not authored with TypeScript, so consumer has option to extend them, if some definition are missing.

Same applies if our library is written in TypeScript and ambient type definitions are generated automatically.

This is the only use case, where you definitely should always use interface instead of type alias !

⚛️: What should I use for React Props and State ?

In general, use what you want ( type alias / interface ) just be consistent, but personally, I recommend to use type aliases:

  • it’s shorter to write type Props = {}
  • your syntax is consistent ( you are not mixin interfaces with type aliases for possible type intersections )
  • your public component Props/State implementation cannot be monkey patched and for that reason, consumer of your component should never need to leverage interface declaration merging. For extension there are clearly defined patterns like HOC and so on.


In this article we learned what is the difference between interface and type alias in latest TypeScript.

With that covered, we came to an conclusion what method of defining compile time types should be used in a particular scenario.

Let’s recap:

  • type aliases can act sort of like interfaces, however, there are 3 important differences ( union types, declaration merging)
  • use whatever suites you and your team, just be consistent
  • always use interface for public API's definition when authoring a library or 3rd party ambient type definitions
  • consider using type for your React Component Props and State

As always, don’t hesitate to ping me if you have any questions here or on twitter (my handle @martin_hotell) and besides that, happy type checking folks and ‘till next time! Cheers!

Principal Engineer | Google Dev Expert/Microsoft MVP | @ngPartyCz founder | Speaker | Trainer. I 🛹, 🏄‍♂️, 🏂, wake, ⚾️& #oss #js #ts

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store