We have seen the primary 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}`;
};
Nothing is 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.
Defining a type
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);
};
Defining an interface
An interface is also a declaration of an 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 replaced the type with an interface declaration.
The difference between a type and interface
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 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 throw an error if we type the same.
type User = {
firstname: string,
lastname?: string,
};
type User = {
id: number,
};
// Duplicate identifier User
So, which one to pick?
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.
Most of the time, an interface will be a perfect fit, and it’s super declarative to what something is.
Thank you for reading, and let’s connect!
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter