Typescript overload function and constructor in a class

Every Object-oriented language provides OOPS concepts of Inheritance, polymorphism, overloading, etc.

Typescript also provides overloading methods and constructors with the same name.

overload is a defined same name with different parameters and returns types.

A typescript is a different approach unlike many other programming languages provide. Typescript also provides this concept, but with a different implementation.
So what is overloading in typescript?

Usually, as per any programming language, we will write the code below.

class OverloadDemo {
  constructor() {}
  method(num: number) {
    console.log("method with number argument");
  }
  method(message: string) {
    console.log("method with string argument");
  }
}
let demo = new OverloadDemo();
console.log(demo.method(12));

It does not work and gives a compilation error and throws Duplicate function implementation. During the compilation of this code into javascript, Both function definitions look the same. So javascript doesn’t understand overloading.
To Fix Duplicate function implementation, provide a single function to have variable arguments.

Overloading applies to functions and constructor in typescript.

Typescript overload methods

Function overloading is to provide the same function name with different arguments. We are providing a simple implementation function in which arguments might be different.

In any overloaded functions, there are different things to be noted
1. Arguments count might be different
2. The argument type is a different type
3. The return type is variable

How can overload works in typescript?

Typescript allows the programmer to write a single function to behave differently based on the number of variable arguments and data type.

We can achieve these in many ways with limitations

Function overload with Any data type

Any data type in typescript is a predefined data type in typescript. a variable declared with Any data type can assign any value. It can be a string or a number.

The same above code rewrites with the below things.

We are providing the only function with a single parameter of type any, We can pass string or number here. In this method, we are providing overload functionality with different arguments, but the arguments count is the same.

class OverloadAnyDemo {
  constructor() {}
  method(num: any) {
    console.log("method ", typeof num);
  }
}
let demo = new OverloadAnyDemo();

console.log(demo.method(12)); // returns number
console.log(demo.method({})); // returns object
console.log(demo.method(true)); // returns boolean

Function overload Using Union Type in typescript

We provide the implementation for an additional function that adds the numbers. Numbers passed to this function might be two or three or more numbers.

Typescript provides a Union Type that contains the union of multiple types under one data type.

class OverloadAnyDemo {
  constructor() {}
  method(message: string | any) {
    console.log("method ", typeof message);
  }
}
let demo = new OverloadAnyDemo();
console.log(demo.method(12)); // returns number
console.log(demo.method({})); // returns object
console.log(demo.method(true)); // returns boolean

Functional overload Using Optional Parameter in typescript

Using optional parameters (symbol is a question mark -?) in functional arguments

method(message?: string | any) {
        console.log('method ', typeof message);
    }

The string argument here is optional, So this function accepts zero or one string as an argument. It is another way to achieve overloading.

Constructor Overloading in typescript

Constructors do create with keyword Constructors in typescript, These are the same as functions with few differences.

Let’s define a Circle class in typescript

class circle {
  radius: number;

  // constructor signature with declared properties
  constructor(radius = 0) {
    this.radius = radius;
  }
}

Let’s add an overloaded constructor

class circle {
  // Constructor Overloads
  constructor(radius: number, color: string);
  constructor(color: string);
  constructor(radius: any, color?: any) {

  }
}

Like function overload, we can have only one constructor with different arguments. It is a valid overload as it will work for the new operator.

Difference between function overload and constructor overload

  • Constructors are not allowed typed parameter
  • type annotations are not allowed in constructor functions, It always returns a class instance
  • only one constructor implementation is allowed in typescript

We can achieve Constructors overload using optional parameters, Any data type, or Union Type.

Typescript overload with arrow functions

Let’s have constructor overload for a circle

class circle {
  // Constructor Overloads
  constructor(radius: number);
  constructor(color: string);

}

You can rewrite the above constructor overloading with the arrow function as

In this example, created a type alias for the above You can rewrite the above constructor overloading with the arrow function as overload with the type keyword

type Circle = {
  (name: number): void,
  (name: string): void,
};
const circle: Circle = (name: number | string): void => {};

And the caller code is like below

circle(5);
circle("red");

Interface overload in typescript

Let’s declare an interface it has two overloaded methods with the same name and different arguments.

interface Shape {
  area(length: number, breadth: number): number;
  area(side: number): number;
}

Suppose you are declaring Rectangle and Square classes

So Rectangle and Square should implement Shape, so we need to implement all methods of the interfaces as seen below

class Rectangle implements Shape {
  area(length: number, breadth: number): number {
    // todo
  }
  area(side: number): number {
    // todo
  }
}

class Square implements Shape {
  area(length: number, breadth: number): number {
    // todo
  }
  area(side: number): number {
    // todo
  }
}

As these shares are not required to calculate area implementation twice. So it is not best to write an interface overloading like above.

We will rewrite the above interface-overloaded methods

interface Shape {
  area:
    | ((length: number, breadth: number) => number)
    | ((side: number) => number);
}

And implementations for Rectangle and Square are as follows

class Rectangle {
  area(length: number, breadth: number): number {
    //todo
  }
}

class HTMLElemeSquaretString {
  area(side: number): number {
    // todo
  }
}

Conclusion

You learned typescript overload with any, optional and union type for

  • function overload
  • constructor overload
  • Arrow functions for overload
  • typescript interface overload methods