TypeScript types and interfaces

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
I used to be confused about them at first. But as you say, they are basically the same thing.
I tend to use interfaces for classes that will implement them. Usually describing the methods they must implement. And types when I just want a short alias for a JavaScript object.
Thanks for sharing :)
Indeed, they look more confusion than they are. Once you used them a couple of times it will become clear what the benefits/downsides to each are.
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

We have seen the basic usage of defining an object in the previous article on TypeScript types. However when we used this object it looked like this:
const getFullName = (user: {firstname: string, lastname: string}): string => {
return `${user.firstname} ${user.lastname}`;
};
Not that there is anything wrong with this, but let's say we need to use this user object again in a saveUser function?
Then we have to copy-paste this same declaration piece all over the place.
And that's where type and interface come in handy.
To define a type, you use it as a variable declaration.
type User = {
firstname: string,
lastname?: string,
};
Then instead of defining these loose objects, we can pass the type to our function.
const getFullName = (user: User): string => {
return `${user.firstname} ${user.lastname}`;
};
And this gives us the option to re-use this type for another function quickly.
const saveUser = (user: User): void => {
return await db.save(user);
};
A interface is also a declaration of a object and it will look like this:
interface User {
firstname: string;
lastname?: string;
}
const getFullName = (user: User): string => {
return `${user.firstname} ${user.lastname}`;
};
As you can see, not much has changed. We simply replaced the type with an interface declaration.
Knowing these two, it's keen to see the actual differences between them.
First of all, it's how we declare them. The type has the extra =, which is unnecessary for an interface.
But that's not the main difference.
The main difference is that a type can never change, so we cannot add new properties to a type. And the interface, on the other hand, can be redeclared.
We have our user interface, but we want a LoggedUser object with an extra ID field.
With interfaces, we can extend the existing one like so:
interface LoggedUser extends User {
id: number;
}
Now the id will be available on this object.
const user: LoggedUser = {
firstname: '',
lastname: '',
id: 34,
};
With types we can however do something similar and it will look like this:
type LoggedUser = User & {
id: number,
};
Which comes down to the same effect.
Now let's look at changing the originals and see what happens.
interface User {
firstname: string;
lastname?: string;
}
interface User {
id: number;
}
This will be valid, and the User interface will now have these three fields. However, I would not recommend this as you will get lost as to what kind of properties an interface should have.
On the other hand, the type will simply throw an error if we type the same.
type User = {
firstname: string,
lastname?: string,
};
type User = {
id: number,
};
// Duplicate identifier User
It mainly comes down to preference. If you don't have one, stick to the interface until you might need something specific to a type.
For most of the time, an interface will be a perfect fit, and it's super declarative to what something is.
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter