Lessons
TypeScript Tutorial
TypeScript Control Structures
TypeScript Function Types
TypeScript Function Overloading
Introduction to TypeScript Function Overloading
In TypeScript, function overloading lets you define multiple function signatures for a single function name. This means you can call the same function with different argument types or numbers, and TypeScript will understand and enforce the correct usage.
Example:
tsx
1 2
function greet(name: string): string; function greet(age: number): string;
Here, greet
is overloaded to accept either a string
or a number
as an argument.
Syntax of TypeScript Function Overloading
Function overloading involves declaring multiple function signatures followed by a single implementation. The implementation must be compatible with all declared signatures.
Example:
tsx
1 2 3 4 5
function add(a: number, b: number): number; function add(a: string, b: string): string; function add(a: any, b: any): any { return a + b; }
In this example, add
can concatenate strings or sum numbers based on the provided arguments.
Implement TypeScript Function Overloads
After declaring the overloads, you provide a single function implementation that can handle all specified cases. Inside this function, you can use type checks to determine the types of the arguments and handle them accordingly.
Example:
tsx
1 2 3 4 5 6 7 8 9 10
function add(a: number, b: number): number; function add(a: string, b: string): string; function add(a: any, b: any): any { if (typeof a === 'number' && typeof b === 'number') { return a + b; // Sum numbers } else if (typeof a === 'string' && typeof b === 'string') { return a + b; // Concatenate strings } throw new Error('Invalid arguments'); }
This implementation ensures that add
functions correctly with both numbers and strings.
Overloading with Optional Parameters
You can overload functions to accept different numbers of parameters by using optional parameters. This allows a function to handle cases where some arguments may or may not be provided.
Example:
tsx
1 2 3 4 5 6 7 8
function sum(a: number, b: number): number; function sum(a: number, b: number, c: number): number; function sum(a: number, b: number, c?: number): number { if (c !== undefined) { return a + b + c; // Sums three numbers } return a + b; // Sums two numbers }
Here, the sum
function can handle both two and three arguments, summing them appropriately.
Method Overloading in Classes
TypeScript allows you to overload methods within classes, enabling class methods to operate differently based on varying parameter types or counts.
Example:
tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class Calculator { calculate(a: number, b: number): number; calculate(a: string, b: string): string; calculate(a: any, b: any): any { if (typeof a === 'number' && typeof b === 'number') { return a * b; // Multiplies numbers } else if (typeof a === 'string' && typeof b === 'string') { return a.concat(b); // Concatenates strings } throw new Error('Invalid arguments'); } } const calc = new Calculator(); console.log(calc.calculate(5, 10)); // Outputs: 50 console.log(calc.calculate('Hello, ', 'World!')); // Outputs: Hello, World!
In this class, the calculate
method is overloaded to either multiply numbers or concatenate strings based on the argument types.
Practical Examples
Example 1: Fetching Data
tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
function fetchData(id: number): object; function fetchData(url: string): object; function fetchData(param: any): object { if (typeof param === 'number') { // Fetch data by ID return { id: param, data: 'Data for ID ' + param }; } else if (typeof param === 'string') { // Fetch data by URL return { url: param, data: 'Data from URL ' + param }; } throw new Error('Invalid argument'); } console.log(fetchData(1)); // Outputs: { id: 1, data: 'Data for ID 1' } console.log(fetchData('https://api.example.com')); // Outputs: { url: 'https://api.example.com', data: 'Data from URL https://api.example.com' }
Example 2: Logging Messages
tsx
1 2 3 4 5 6 7 8 9 10 11 12
function log(message: string): void; function log(error: Error): void; function log(param: any): void { if (typeof param === 'string') { console.log('Message: ' + param); // Logs message } else if (param instanceof Error) { console.error('Error: ' + param.message); // Logs error } } log('System started'); // Outputs: Message: System started log(new Error('System failure')); // Outputs: Error: System failure
These examples demonstrate how function overloading can be used to handle different types of inputs within the same function, making your code more versatile and easier to maintain.
Best Practices TypeScript Function Overloading
- Consistent Parameter Counts: Ensure that overloaded functions have the same number of required parameters. If there are differences, use optional parameters to maintain consistency.
- Comprehensive Type Checking: Implement thorough type checks within the function body to handle all specified overloads correctly.
- Clear Documentation: Document each overload to provide clarity on the function's behavior with different argument types.
- Avoid Excessive Overloading: While overloading adds flexibility, too many overloads can make the codebase harder to maintain. Use overloading judiciously.