How to Overload Constructors in TypeScript

  1. Overload Constructors to Initialize Classes in TypeScript
  2. Use Static Factories as Alternative to Constructor Overloading in TypeScript
How to Overload Constructors in TypeScript

Constructor overloading is an essential concept in programming. We can have different constructors of the same class distinguished by the number and type of the parameters.

TypeScript also supports constructor overloading; however, it is different from the conventional constructor overloading found in languages like C++ or Java.

This article will discuss using constructor overloading to implement various kinds of business logic.

Overload Constructors to Initialize Classes in TypeScript

In TypeScript, the constructors can be overloaded by declaring many constructors or having the single constructor accompanied by the ? and union operators. However, all the constructors must have a common implementation.

The following code segments explain how this can be achieved.

class Fruits {
    public apple : string | number;
    public numBananas : number;
    public unknownFruit : string;
    // default
    constructor();

    // // parameterized constructors
    constructor(a : string );
    constructor(a : string , b : number );
    constructor(a : number , b : number, c : string );

    // common implementation
    constructor( a? : string | number, b? : number, c? : string ){

        this.apple = 0;
        if ( a !== undefined ){
            this.apple = a;
            if ( typeof a === "string"){
                console.log("Got apple of country: ", this.apple);
            } else if ( typeof a === "number") {
                console.log("Number of apples got: ", this.apple);
            }
        } else {
            console.log("Apple field assigned 0 by default constructor");
        }
        this.numBananas = b ?? 0;
        this.unknownFruit = c ?? "";
    }
}
var fruitDefaultConstrutor = new Fruits();
var fruitWithOnlyAppleDecalred = new Fruits("India");
var fruitWithAppleBananaDecalred = new Fruits("India", 4);
var fruitWithAppleBananaUnkwownDeclared = new Fruits(8, 4, "Orange");

Output:

"Apple field assigned 0 by default constructor"
"Got apple of country: ",  "India"
"Got apple of country: ",  "India"
"Number of apples got: ",  8

We have defined multiple constructors in the Fruits class. The default constructor has no parameters, while the others have different numbers of parameters with varying types.

All the constructors have a single implementation. The various types for a parameter are represented by the union operator or the | as seen in a? : string | number.

After a parameter, the ? operator denotes that this field may remain empty when calling the constructor, allowing us to implement different constructor definitions through a single implementation.

Calling new Fruits("India", 4, "Orange") would, however, give an error as there are no compatible constructor definitions, although the types of the common implementation method are satisfied.

We can improve this by removing the constructor definitions and having only the common implementation.

class Fruits {
    public apple : string | number;
    public numBananas : number;
    public unknownFruit : string;

    // common implementation
    constructor( a? : string | number, b? : number, c? : string ){

        this.apple = 0;
        if ( a !== undefined ){
            this.apple = a;
            if ( typeof a === "string"){
                console.log("Got apple of country : ", this.apple);
            } else if ( typeof a === "number") {
                console.log("Number of apples got : ", this.apple);
            }
        } else {
            console.log("Apple field assigned 0 by default constructor");
        }
        this.numBananas = b ?? 0;
        this.unknownFruit = c ?? "";
    }
}

Output:

"Got apple of country : ",  "India"

Thus, constructors can be overloaded for initializing different fields or setting up some initial logic.

Use Static Factories as Alternative to Constructor Overloading in TypeScript

The constructor overloading logic can soon get ugly when handling many constructors and using the ? and union operator. Another way to initialize classes is through the static factory pattern in TypeScript.

The following code segment will discuss how we can achieve this.

class Fruits {
    public apple : string | number;
    public numBananas : number;
    public unknownFruit : string;

    constructor(){
        this.apple = "";
        this.numBananas = 0;
        this.unknownFruit = "";
    }
    static fromAppleCountry( a : string) : Fruits {
        var fruits = new Fruits();
        fruits.apple = a;
        console.log("Got apple of country : ", fruits.apple);
        return fruits;
    }
}

var fruitWithOnlyAppleDecalred = Fruits.fromAppleCountry("India");

Output:

"Got apple of country : ",  "India"
Shuvayan Ghosh Dastidar avatar Shuvayan Ghosh Dastidar avatar

Shuvayan is a professional software developer with an avid interest in all kinds of technology and programming languages. He loves all kinds of problem solving and writing about his experiences.

LinkedIn Website

Related Article - TypeScript Constructor