Type vs Interface in TypeScript - When to choose what

Before TypeScript 2.1 there was a lots of difference between interface and type in TypeScript. But now with TypeScript > 5.x there is very less difference with both. What we can do using interface, can do easily also with type for almost 95% cases.

Let’s see an example of Same works with both interface and type -

Interface

interface Point {
  x: number;
  y: number;
}

interface SetPoint {
  (x: number, y: number): void;
}

Type alias

type Point = {
  x: number;
  y: number;
};

type SetPoint = (x: number, y: number) => void;

So, we can see in the above example that we can do same stuff with type and interface.

Extend with interface and type

Both can be extended, but again, the syntax differs. Additionally, note that an interface and type alias are not mutually exclusive. An interface can extend a type alias, and vice versa.

Interface extends interface

interface PartialPointX { x: number; }
interface Point extends PartialPointX { y: number; }
Type alias extends type alias

type PartialPointX = { x: number; };
type Point = PartialPointX & { y: number; };
Interface extends type alias

type PartialPointX = { x: number; };
interface Point extends PartialPointX { y: number; }
Type alias extends interface

interface PartialPointX { x: number; }
type Point = PartialPointX & { y: number; };

Implements

A class can implement an interface or type alias, both in the same exact way. Note however that a class and interface are considered static blueprints. Therefore, they can not implement / extend a type alias that names a union type.

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// FIXME: can not implement a union type
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

Declaration merging

Unlike a type alias, an interface can be defined multiple times, and will be treated as a single interface (with members of all declarations being merged).

// These two declarations become:
// interface Point { x: number; y: number; }
interface Point { x: number; }
interface Point { y: number; }

const point: Point = { x: 1, y: 2 };

Difference and matches between interface and type

Aspect Type Interface
Can describe functions
Can describe constructors
Can describe tuples
Interfaces can extend it ⚠️
Classes can extend it 🚫
Classes can implement it (implements) ⚠️
Can intersect another one of its kind ⚠️
Can create a union with another one of its kind 🚫
Can be used to create mapped types 🚫
Can be mapped over with mapped types
Expands in error messages and logs 🚫
Can be augmented 🚫
Can be recursive ⚠️

What should We Use?

Use interfaces when:

  1. A new object or an object method needs to be defined.
  2. You wish to benefit from declaration merging.

Use types when:

  1. You need to define a primitive-type alias
  2. Defining tuple types
  3. Defining a union
  4. You must create functions and attempt to overload them in object types through composition.
  5. Requiring the use of mapped types
Previous
Advanced Types in TypeScript - In depth Types Learning in TypeScript