Hands-On Functional Programming with TypeScript
上QQ阅读APP看书,第一时间看更新

Function overloading

Function, or method, overloading is the ability to create multiple methods with the same name and a different number of parameters or types. In TypeScript, we can overload a function by specifying all function signatures (known as overload signatures) of a function, followed by a signature (known as the implementation signature). Let's look at an example:

function test(name: string): string; // overloaded signature
function test(age: number): string; // overloaded signature
function test(single: boolean): string; // overloaded signature
function test(value: (string|number|boolean)): string { // implementation signature
switch (typeof value) {
case "string":
return 'My name is ${value}.';
case "number":
return 'I'm ${value} years old.';
case "boolean":
return value ? "I'm single." : "I'm not single.";
default:
throw new Error("Invalid Operation!");
}
}

As we can see in the preceding example, we have overloaded the function test three times by adding a signature that takes a string as its only parameter, another function that takes a number, and a final signature that takes a Boolean as its unique parameter. It is important to note that all function signatures must be compatible; so, if, for example, one of the signatures tries to return a number while another tries to return a string, we will get a compilation error:

function test(name: string): string;
function test(age: number): number; // Error
function test(single: boolean): string;
function test(value: (string|number|boolean)): string {
switch (typeof value) {
case "string":
return 'My name is ${value}.';
case "number":
return 'I'm ${value} years old.';
case "boolean":
return value ? "I'm single." : "I'm not single.";
default:
throw new Error("Invalid Operation!");
}
}

Please note that this restriction can be overcome by using a specialized overloaded signature, as we will learn in the following section.

The implementation signature must be compatible with all the overloaded signatures, always be the last in the list, and take any or a union type as the type of its parameters.

Invoking the function by providing arguments that don't match any of the types declared by the overload signatures will lead to a compilation error:

test("Remo"); // returns "My name is Remo."
test(29); // returns "I'm 29 years old.";
test(false); // returns "I'm not single.";
test({ custom: "custom" }); // Error