Function and method overloading in TypeScript

In Typescript, the declaration of an overload is defined by writing overload signatures.

To do this, write some number of function signatures (usually two or more), followed by the body of the function

Be aware that the implementation signature type should be generic enough to include the overload signatures.

For example, an improper implementation signature:

1
2
3
4
5
6
7
function fn(x: string): string;
// Return type isn't right
function fn(x: number): boolean;
// This overload signature is not compatible with its implementation signature.
function fn(x: string | number) {
  return  "oops";
}

Function overloading

Define a speak function that accepts a string or a number in the signature.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function speak(message: string): string;
function speak(num: number): string;
function speak(m: unknown) {
  if (typeof m === 'string') {
    return m;
  } else  if (typeof m === 'number') {
    return  `${m}`
  }
  throw  new  Error('Unable to greet');
}
console.log(speak(15)); // "15"
console.log(speak("a message")); // "a message"

In the implementation signature, m is of value unknown and covers both overloaded signatures.

Method overloading

Using the same technique as before, the speak method can be included in a class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class  Speaker {
  speak(message: string): string;
  speak(num: number): string;
  speak(m: unknown): unknown {
    if (typeof m === 'string') {
      return m;
    } else  if (typeof m === 'number') {
      return  `${m}`
    }
    throw  new  Error('Unable to greet');
  }
}
console.log(new  Speaker().speak(15));
console.log(new  Speaker().speak("a message"));