Function overrides

As JavaScript is a dynamic language, we can often call the same function with different argument types. Consider the following JavaScript code:

function add(x,y) { 
    return x + y; 
} 
 
console.log('add(1,1)=' + add(1,1)); 
console.log('add("1","1")='' + add("1","1"));

Here, we are defining a simple add function that returns the sum of its two parameters, x and y. We are then simply logging the result of the add function with different types two numbers and two strings. If we run the preceding code, we will see the following output:

add(1,1)=2
add("1","1")=11

In order to reproduce this ability to call the same function with different types, TypeScript introduces a specific syntax, called function overrides. If we were to replicate the preceding code in TypeScript, we would need to use this function override syntax, as follows:

function add(a: string, b: string) : string; 
function add(a: number, b: number) : number; 
function add(a: any, b: any): any { 
    return a + b; 
} 
 
console.log(`add(1,1)= ${add(1,1)}`); 
console.log(`add("1","1")= ${add("1","1")}`);

Here, we specify a function override signature for the add function that accepts two strings and returns a string. We then specify a second function override that uses the same function name but uses numbers as parameters. These two function overrides are then followed by the actual body of the function. The last two lines of this snippet are calling the add function, firstly with two numbers, and then with two strings. The output of this code is as follows:

add(1,1)= 2
add("1","1")= 11

There are three points of interest here. Firstly, none of the function signatures on the first two lines of the snippet actually have a function body. Secondly, the final function definition uses the type specifier of any and eventually includes the function body. To override functions in this way, we must follow this convention, and the final function signature (that includes the body of the function) must use the any type specifier, as anything else will generate compile-time errors.

The last point to note is that even though the final function body uses the type of any, this signature is essentially hidden by using this convention. We are actually limiting the add function to only accept either two strings, or two numbers. If we call the function with two boolean values, as follows:

console.log(`add(true,false)= ${add(true,false)}`); 

TypeScript would generate compile errors:

error TS2345: Argument of type 'true' is not assignable to parameter of type 'number'.