How to create class constructor overloads in TypeScript?

Published April 21, 2022

To create overloads for class constructors in TypeScript, you need to use the constructor keyword followed by the parameters brackets ending with the ; symbol (semi-colon) and you need to write this just above the original constructor definition itself.

Constructor overloads are similar to function overloads in TypeScript.

TL;DR

// a simple class
class Car {
  name: string;
  yearMade: number;

  // constructor overload here
  constructor(yearMade: number);
  constructor(yearOrName: any, yearMade?: any) {
    // check for types and then
    // do assignment to fields if needed
    // now we are just assiging it
    // without checking for the types
    this.name = yearOrName;
    this.yearMade = yearMade;
  }
}

For example, let's say we have a class called Car with 2 fields like name having string type and yearMade having number type and a constructor to initialize the value of those fields like this,

// a simple class
class Car {
  name: string;
  yearMade: number;

  constructor(name: string, yearMade: number) {
    this.name = name;
    this.yearMade = yearMade;
  }
}

Now to make a constructor overload that accepts only one parameter called yearMade, we need to write the new constructor overload definition above the original constructor definition like this,

// a simple class
class Car {
  name: string;
  yearMade: number;

  // constructor overload here
  constructor(yearMade: number);
  constructor(name: string, yearMade: number) {
    this.name = name;
    this.yearMade = yearMade;
  }
}

But there is one more thing we need to sort out in the above code because as soon as we added the new constructor overload TypeScript throws an error saying that This overload signature is not compatible with its implementation signature.. This is because the constructor overload we just wrote has to have the compatible types in the parameters like in the original constructor definition itself.

So in our case, the first parameter yearMade is having the type of number in the constructor overload but the original definition is having the parameter name that is having the type of string.

So to make it a compatible type let's, for now, use the any type in the original definition parameters and use the second parameter yearMade in the original constructor definition as optional using the ? symbol (question mark). We are making the second parameter optional because in our case the overload we wrote only has one parameter.

It can be done like this,

// a simple class
class Car {
  name: string;
  yearMade: number;

  // constructor overload here
  constructor(yearMade: number);
  constructor(name: any, yearMade?: any) {
    this.name = name;
    this.yearMade = yearMade;
  }
}

For readability purposes let's name the first parameter of the original constructor as yearOrName since it can accept both name or the year like this,

// a simple class
class Car {
  name: string;
  yearMade: number;

  // constructor overload here
  constructor(yearMade: number);
  constructor(yearOrName: any, yearMade?: any) {
    // check for types and then
    // do assignment to fields if needed
    // now we are just assiging it
    // without checking for the types
    this.name = yearOrName;
    this.yearMade = yearMade;
  }
}

The body of the constructor should ideally be checking for the type and then assigning the values to the class fields but here I'm leaving it as homework for you.

We have successfully made a class constructor overload in TypeScript. Yay 🥳!

See the above code live in codesandbox.

That's all 😃!

Feel free to share if you found this useful 😃.


Share on: Facebook Twitter