Type aliases and interfaces are TypeScript language features that often confuse people who try TypeScript for the first time. What’s the difference between them? When should we use one over the other?
Type aliases and interfaces used to be quite different in their capabilities. However, it’s no longer true in the latest versions of TypeScript. Over time they have grown together to the point when they are almost identical. They still have some subtle differences — interfaces are more “extendable” due to the support of declaration merging, and types are more “composable” due to support of union types. We’ll talk about these differences in more details a bit later.
Owing to the nature of differences between type aliases and interfaces, the decision to use one over another usually depends on your preferred programming style. If you write object-oriented code — use interfaces, if you write functional code — use type aliases.
Now let’s talk about React.
React is more functional by nature. Functional components are generally preferred over class-based components. Hot and shiny React Hooks are just functions used inside functional components. HOCs, Redux, pure functions, and a handful of other concepts widely used in React come from a functional world. So for these reasons,
In React applications, just use type aliases.
Now let’s see why.
1. Power of interfaces isn’t useful in React applications
One of the main things that differentiate interfaces from type aliases is the ability to merge declarations. With interfaces, we can re-open previously declared interfaces and add additional properties to it:
The code above doesn’t have any errors, because the resulting IUser
interface will contain all 3 properties — firstName
, lastName
, and age
.
This is a very powerful feature that allows us to write type declarations for 3rd party libraries and gives us an option to extend them. However, In regular React application, this feature doesn’t bring any value. On the contrary, it can introduce unnecessary complexity and add bugs if somebody will try to monkey-patch props or state interfaces.
2. Type aliases are more composable
One thing that type aliases can do that interfaces can’t is create an intersection with a type alias that uses union operator within its definition:
This can be useful when we want to combine component’s own props with some HOC’s props that might use union operator.
3. Type aliases require less typing (as in typing on the keyboard)
It’s simply faster to type type Props
than interface IProps
.
4. Consistency
First of all, we don’t want to mix interfaces and types. It’s a common convention to prefix interface names with I
, so we’ll have a mix of IProps
interfaces and Props
type aliases in our code. Not only will it create unnecessary clutter, but also increase required mental effort every time we need to think: “Do we have IProps
interface or Props
type aliases here?”
Second, we won’t be able to just use interfaces either. As we mentioned earlier, type composition is a very useful feature for React applications, and because interfaces cannot be combined with union-based types, at some point we may need to change our interfaces to type aliases. That means that we’ll also have to rename IProps
to Props
to avoid further confusion. And if the type is exported, we have to rename all the occurrences in the code as well. This extra work can be avoided by simply using type aliases everywhere.
Conclusion
Hopefully, this article helped you to see the difference between interfaces and type aliases in TypeScript and also convinced you that type aliases are preferable for React applications.
If you disagree with any of the points or feel that something is missing, please let me know in the comments. In the meantime, go ahead and disable interface-over-type-literal
setting in TS Lint and start using type aliases in your React applications!
Shameless plug: if you want to learn how to use Redux without writing a ton of boilerplate, check my "State management with Rematch" course on Youtube.
Top comments (1)
There is also one interesting difference between interfaces and types - it is how they are indexed. Here you can find SO answer: stackoverflow.com/questions/372337...
and related reddit thread: reddit.com/r/typescript/comments/r...