Interface vs Type alias

ℹ️ They are similar in many ways. The key differences are: type can be used for primitives and type can be used for union of other types/interfaces.

Mostly, type alias is used to represent a more complex type like the union of a few different types:

type Figure = IRectangle | ICircle;

Interfaces are used to represent the shape of an object (for example, to create classes or to use in function parameters):

Person.js
interface IPerson {
  name: string;
  age: number;
  sayHi(): void;
}

// Example:
class Person implements IPerson {
  constructor(public name, public age) {}

  public sayHi() {
    console.log('Hello!');
  }
}

Type aliases and interfaces are similar in many ways, except syntax. Nevertheless, they have differences that you need to know.

Similarities

An object can be represented using both interface and type:

interface IPlayer {
  name: string;
  age: number;
  jump(): void;
}

type PlayerType = {
  name: string;
  age: number;
  jump(): void;
};

// We can assign variable with the `IPlayer` interface
// to variable with `PlayerType`, or vice versa.
let player: IPlayer;
let playerType: PlayerType;

player = playerType;

Interfaces can create the same structure as type aliases, except types union and primitives:

type Jump = () => void;
type PlayersIDs = string[];

// 🔽 Equivalent using interfaces
interface IJump {
  (food: string): void;
}

interface IPlayersIDs {
}

It's also possible to merge interfaces or types:

type IMerged = IFirst & ISecond;
// or
interface IMerged extends IFirst, ISecond {}

Differences

Primitive types

It's possible to describe primitive only with the type alias:

type Name = string;

As mentioned above, type alias can be used to describe the union:

Type Alias union

interface ICircle {}
interface ISquare {}

type ShapeType = ICircle | ISquare;

ℹ️ Note: a type alias with union can't be used inside interface or class anymore, what is logic, as class or interface can only represent a specific structure, not one or another.

Mapped Types

With type alias it's possible to create mapped types:

type Keys = 'name' | 'breed';

type Flags = { [K in Keys]: boolean };

Declaration Merging is possible only with interfaces

You can define the same interface multiple times, and their definitions will be merged into one:

interface Dog {
  name: string;
  breed: string;
}

// ....

interface Dog {
  age: number;
}

let oscar: Dog = { age: 5, breed: 'pug', name: 'Oscar' }; // --> ✅ valid
console.log(oscar.breed, oscar.age);

Read More

Last updated