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