Book Your Free Call

Top 9 Differences Between Type VS Interface in TypeScript

Tim Mouskhelichvili
Tim Mouskhelichvili
4 minutes to read

In TypeScript, both an interface and a type alias can be used to describe a new named type. Since in most cases, almost all features are available in both, developers are sometimes using them interchangeably. This brings confusion and begs the question of type vs interface, which to use, and in which case.

The most important differences between a type vs interface are:

  1. An interface can participate in declaration merging, but a type cannot.
  2. An interface cannot declare a primitive (number, string, tuple, etc...), but a type can.
  3. Only a type can use mapped properties.

In this article, I will go over, in detail, all the differences between a type vs an interface and will explain which to use and when.

Let's get to it 😎.

typescript type vs interface

1. Primitive Types

A primitive type can only be declared with a type.

If you try to declare one with an interface, it will not work.

typescripttype AString = string;
type BNumber = number;
type CBoolean = boolean;
type DArray = string[];
type EUnknown = unknown;
type FAny = any;
type GNull = null;
type HUndefined = undefined;

2. Declaration Merging

Declaration merging is only possible with an interface.

In TypeScript, declaration merging happens when the compiler merges two or more interfaces of the same name into one. On the other hand, if you try to declare two types of the same name, the compiler will throw an error.

Here is an example of declaration merging in TypeScript.

typescriptinterface IArticle {
    content: string;
}

interface IArticle {
    category: string;
}

const article: IArticle = {
    category: 'news',
    content: 'new content'
};

In this example, we first declare the IArticle interface with one property. Then, we declare it another time, with a different property. Finally, the compiler merges both interfaces into one, since they share the same name.

3. Inheritance and Extends

Both a type and an interface can be extended, but with a slightly different syntax.

Here is an example of how an interface can extend another interface.

typescriptinterface IArticleContent { 
    content: string;
}

interface IArticle extends IArticleContent { 
    category: string;
}

Here is an example of how a type can extend another type.

typescripttype ArticleContent = { 
    content: string;
}

type Article = ArticleContent & { 
    category: string;
}

Note: With TypeScript, you can extend a type with an interface, and vice-versa, when using the extend feature.

Here is a complete guide on how to extend a type in TypeScript.

4. Implements

Both a type and an interface can be implemented by a class.

Here is an example of how a class can implement an interface.

typescriptinterface IArticle { 
    category: string;
    content: string;
}

class Article implements IArticle {
    public category = '';
    public content = '';
}

Here is an example of how a class can implement a type.

typescripttype MyArticle = { 
    category: string;
    content: string;
}

class Article implements MyArticle {
    public category = '';
    public content = '';
}

Note: You cannot implement/extend a union-type type alias.

5. Tuples

A tuple can only be declared with a type.

If you try to declare one with an interface, it will not work.

Here is an example of a tuple declaration in TypeScript.

typescripttype MyTuple = [ string, number ];

I've written an extensive blog post about how does the tuple work in TypeScript.

6. Intersection

Intersection types allow the developer to merge two or more type declarations into one.

You can use the intersection & operator to create a new type, both with types and with interfaces. However, the combined declaration must always be a type.

Here is an example of how to combine two types with an intersection.

typescripttype MyArticle = {
    content: string;
}

type ArticleContent = {
    category: string;
}

type Article = MyArticle & ArticleContent;

const article: Article = {
    category: 'news',
    content: 'new content'
}; 

Here is an example of how to combine two interfaces with an intersection.

typescriptinterface IArticle {
    content: string;
}

interface IArticleContent {
    category: string;
}

type Article = IArticle & IArticleContent;

const article: Article = {
    category: 'news',
    content: 'new content'
}; 

7. Union

A union type allows the developer to create a new type that can be either type A or type B.

You can use the union | operator to create a new union type, both with types and with interfaces. However, the combined declaration must always be a type.

Here is an example of a union of two types.

typescripttype Cat = {
    name: string;
};

type Dog = {
    name: string;
};

type Animal = Cat | Dog;

Here is an example of a union of two interfaces.

typescriptinterface ICat {
    name: string;
}

interface IDog {
    name: string;
}

type Animal = ICat | IDog;

8. Mapped Properties

Currently, you can only use mapped properties with a type.

Here is an example of a generic mapped type.

typescripttype MyConfig<T> = {
  [Property in keyof T]: string;
};

If you try to do the same with an interface, the compiler will give you an error (A computed property name must be of type 'string', 'number', 'symbol', or 'any').

9. Performance

In earlier versions of TypeScript, there was a performance benefit of using an interface over a type, especially for intersections. However, since TypeScript version 4.2 was released, this performance benefit is no longer there, so you can choose to use either or.

Final thoughts

Although, in most cases, even if you can use either a type or an interface, you shouldn't use them interchangeably... You should however create a rule and follow it in your TypeScript repository. It will help you and other developers understand easier and faster your code.

In my case, I always use an interface, unless I need to use a specific feature that only a type has (tuple or another primitive, mapped properties, etc...).

typescript type vs interface

When do you use the interface vs the type? Write your answer down below (I always respond).

I hope you've enjoyed this article, please share it with your fellow TypeScript developers.

Comments (0)