Types vs Interfaces in TypeScript

RMAG news

To describe complex types, we can use two TypeScript entities: types or interfaces. In the post we will look into their differences and similarities.

Both allow us to create reusable structures for variables, function parameters, return types, and more. In many cases, types and interfaces are interchangeable and can be used similarly to function expression and function declaration:

type PersonType = {
number: string;
age: number;
isFemale: boolean
}

interface PersonInterface {
number: string;
age: number;
isFemale: boolean
}

However, there are slight differences that are important to consider:

Types allow you define types that can hold primitive types or union types within a single definition. This isn’t possible with interfaces, with them you can only define objects.

type A = number;
type B = A | string;

Multiple interfaces with the same name and in the same scope are automatically merged. This is a feature called declaration merging. Types, on the other hand, are immutable. Multiple type aliases with the same name in the same scope will throw an error:

interface User {
email: string;
}

interface User {
password: string;
}

// No error

const user: User = {
email: email,
password: password,
};

// ————————————-

type User = {
email: string;
}

type User = {
password: string;
}

// Error

When you extend an interface, TypeScript will make sure that the interface you’re extending is assignable to your extension. If not, it will throw an error which is quite helpful. This is not the case when you use intersection types: here, TypeScript will do its best to combine your extension.