Interfaces vs type alias in Typescript
interface vs type alias

Interfaces vs type alias in Typescript

Interfaces vs type alias in Typescript

If you want to use a named type in Typescript then you can use type alias or interface but there has been a lot of confusion around whether to use interface or type alias to define your own types and hopefully, after reading this article you will be sure which one to use when. Normally people start by defining similarities between interfaces and types but what I would like to do here is start with the differences between both.

Union Types with interfaces and type alias

Union types are one of the very powerful features in typescript but unfortunately, you can not define them with interfaces.

Normally you define unions as following which throws an error if you do the same with interfaces.

type EmployeId = string | number;

interface EmployeeId = string | number // Error: 'number' only refers to a type, but is being used as a value here

        

Tuples and array types

type aliases can easily express tuples and array types but it's rather more difficult with interfaces and also drop some common array methods like concat, push etc on these types.


//  with type alias

type TPairs = [number,number]
const tpairs: TPairs = [100, 120]; //OK

//  with interfaces

interface IPairs {
	0: number;
	1: number;
	length: number;
}

const ipairs: IPairs = [100, 120]; 

//OK, but with limitations. Array methods are not available with 
intelisense
        

Declaration merging in Interfaces

One of the most useful and powerful features that typescript offers with interfaces is declaration merging. type alias does not support this.

Typescript merge interfaces that have the same names and this is very powerful because it allows you to extend interfaces that are available in global libraries. For example, let's say you are running typescript in the browser. As the window object is globally available in all browser apps we sometimes want to add our own properties to it.


window.token = "mytokenvalue" 

//  Error: Property 'token' does not exist on type 'Window & typeof 
globalThis'
        

if we do this with the declaration merging typescript will allow this.


interface Window{
	token: string
}

window.token = "mytokenvalue"
console.log(window.token) //  Ok 
        

Instead of creating a new `Window` type what typescript did is extended the existing window object type and added `token` attribute to it of type `string`. Now you can use all window properties plus the newly attached token to it.

This technique is primarily used with declaration files where we can extend types from different libraries and modules. Unfortunately, this is not available with type alias so whenever you want to leverage this technique and you want developers to merge their types with your library type then always use interfaces.

extend and intersection(&)

Interfaces can be extended but type aliases can not be extended, we need to use intersection in order to extend type aliases.


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

interface ThreeDVector extends TwoDVector {
	z: number;
}

const vector: ThreeDVector = { x: 10, y: 20, z: 30 };
        

with type aliases, we have to use ‘&’ intersection to extend types.


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

type ThreeDVector = TwoDVector & { z: number };

const vector: ThreeDVector = { x: 10, y: 20, z: 30 };
        

That's all the differences that I know. If you know more add your comments below 👇. Now let's discuss the similarities between interfaces and types 😁

Index Signature

we can use index signature with both types and interfaces.


type TDictionary = { [key: string]: string };

interface IDictionary {

  [key: string]: string;
}

//  Both are Ok
        

Function types

we can define function types with bother interfaces and type aliases.


type Tfunc = (x: number) => string;
interface Ifunc {

  (x: number): string;
}

const convertToString: Tfunc = x => '' + x;  // OK
const convertToString: Ifunc = x => '' + x;  // OK
        

Generic types

Both type aliases and interfaces can be used with generics.


type Tgen<T> = {

  first: T;
  second: T;
}
interface Igen<T> {
  first: T;
  second: T;
}
        

Class implementation

classes can implement both type aliases and interfaces.


type Tgen<T> = {
	first: T;
	second: T;
};

interface Igen<T> {
	first: T;
	second: T;
}

class StateT implements Tgen<string> {
	first: string = '';
	second: string = '';
}

class StateI implements Igen<string> {
	first: string = '';
	second: string = '';
}
        

That's all for now. I hope after reading this you know all the differences and similarities between type aliases and interfaces. See you next week with another Typescript topic. For any questions, you can add your comment or send me a message directly.

To view or add a comment, sign in

More articles by Muhammad Usman

  • Debezium CDC + Outbox on Kubernetes (with Helm)

    TL;DR: We stopped publishing Kafka events directly from our service code and moved to Change Data Capture (CDC) with…

    1 Comment
  • Typescript Generics

    Often in typescript, we want to write reusable code that can work with different types of data. We assume that this…

  • My love-hate relationship with Typescript

    My love-hate relationship with Typescript Well, you all can understand my pain as how confusing Typescript can be…

Others also viewed

Explore content categories