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):

interface IPerson {
  name: string;
  age: number;
  sayHi(): void;

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

  public sayHi() {

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


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 {}


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