skip to content
bastola.us

Types vs. Interfaces in Typescript

In TypeScript, both types and interfaces can be used to define custom types, but there are some differences in their syntax and functionality.

Note: The term “Types” in this article is referring to the”type” aliases in Typescript

According to the official Typescript document: “TypeScript is an open-source language that builds on JavaScript, one of the world’s most used tools, by adding static type definitions.” Implementing typescript on our project saves a lot of time in the long run. But as a developer, we should follow the best practices and standards when working with types in typescript. In this article, we will take a look at the differences between two types type aliases and interface. Many developers don’t really know the real difference between these two. Having known the differences, we can implement these according to the best use case for us.

Origin

Interfaces are used to define data structures, for example, an Object’s shape/structure.

Types are used to define the type of data, for example: Primitive, Union, Intersection, Tuple data types.

Type Evaluation Time

There is a subtle key difference in the type evaluation period. Type evaluation on type aliases is immediate while Type evaluation on the interface is lazy.

Type Declaration Syntax

Even though both types and interfaces can be used in a similar way, their declaration syntax differs.

type BulldogType = {
  name: string;
  height: number;
  weight: number;
}

interface BulldogInterface {
  name: string;
  height: number;
  weight: number;
} 

Extends & Implements keyword

In Typescript, we can extend and implement types using the interface. This is not possible using the type aliases.

interface Dog {
  breed: string;
}

interface Bulldog extends Dog {
  isCute: true;
}

Intersection

We can combine multiple types and interface with the”&” keyword into a single type. But, we cannot combine them into a single interface.

type Bulldog = { }
type GermanShepherd = {}

type DogBreeds = Bulldog & GermanShepherd; // valid

interface IBulldog {}
interface IGermanShepherd {}

type IDogBreeds = IBulldog & IGermanShepherd; // valid
  

Unions

Union types allow us to create a new type that can have a value of one or a few more other types with the”|” keyword. We can combine multiple types and interface with the union keyword into a single type. But, we cannot combine them into a single interface.

type Bulldog = { }
type GermanShepherd = {}

type DogBreeds = Bulldog | GermanShepherd; // valid

interface IBulldog {}
interface IGermanShepherd {}

type IDogBreeds = IBulldog | IGermanShepherd; // valid

Declaration merging

interface allows for declaration merging whilst type aliases don’t. Typescript compiler intelligently merges two or more interfaces that share the same name into only one declaration.

interface IBulldog {
 name: string;
}
interface IBulldog {
 weight: number;
}

const bruno: IBulldog = {
  name: "Bruno",
  weight: 22
}

But type aliases can’t be changed once a type is created using the type alias. So, declaration merging isn’t possible with the type aliases.

type IBulldog = {
 name: string;
}
type IBulldog = {
 weight: number;
}

// Error: Duplicate identifier 'IBulldog'