Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
June 16, 2022 01:45 pm GMT

Quick guide to Function Overloading in TypeScript

We use functions all the time in our apps, generally speaking most of the JS code are functions. TypeScript gives us many ways to describe them.
For a basic function, this is fairly easy to do, but what if the function takes a variety of argument counts and types, or even returns a different type depending on how it's called?
For such cases, TypeScript has the handy function overloading feature. Let's see how to use it and how it can help you improve your code.

Function typing

I feel hungry now, so let's create a function that will cook a dish:

function cookDish(ingredient: string): string {  return `${ingredient} is ready, bon apptit!`;}

We passed a single string argument as an ingredient and it returns a string dish after invocation:

cookDish(''); // ' is ready, bon apptit!'

But wait, this is not enough, I definitely need a sandwich here!
To cook it, we need to modify our function, so that it could accept multiple ingredients:

function cookDish(ingredient: string | string[]): string {  const tableSet = ' is ready, bon apptit!';  if (typeof ingredient === 'string') {    return `${ingredient}${tableSet}`;  } else if (Array.isArray(ingredient)) {    return `${ingredient.join('')}${tableSet}`  }  throw new Error('Nothing to cook ');}

We used Union type to describe our function argument, that can be either one string or multiple string[] of them:

cookDish(''); // ' is ready, bon apptit!';cookDish(['', '', '']); // ' is ready, bon apptit!';

Adding types to support various arguments is a common and good approach in most cases, but sometimes you need to explicitly define all the ways to call a function. This is where function overloading comes into play.

Function overloading

In the case of a rather complex function, to improve usability and readability, it is always better to use the function overloading feature to improve usability and readability. This approach is considered the most flexible and transparent.

To use this, we need to write some function signatures:

  1. Overload signature - defines different ways to call a function: arguments and return types, and doesn't have a body. There can be multiple overload signatures (usually two or more).
  2. Implementation signature - provides an implementation for a function: function body. There can be only one implementation signature and it must be compatible to overload signatures.

Let's rewrite our cookDish using function overloading:

// Overload signaturefunction cookDish(ingredient: string): stringfunction cookDish(ingredients: string[]): string// Implementation signaturefunction cookDish(ingredient: any): string {  const tableSet = ' is ready, bon apptit!';  if (typeof ingredient === 'string') {    return `${ingredient}${tableSet}`;  } else if (Array.isArray(ingredient)) {    return `${ingredient.join('')}${tableSet}`  }  throw new Error('Nothing to cook ');}

Two overload signatures describe two different ways the function can be called: with string or string[] argument. In both ways we will get a cooked string dish as a result.
An implementation signature defines the behavior of a function within a function body.
Our function invocation doesn't change though, we can cook as before:

cookDish(''); // ' is ready, bon apptit!';cookDish(['', '', '']); // ' is ready, bon apptit!';const money: any = 100;cookDish(money);/** No overload matches this call.Overload 1 of 2, '(ingredient: string): string', gave the following error.  Argument of type 'any' is not assignable to parameter of type 'string'.Overload 2 of 2, '(ingredients: string[]): string', gave the following error.  Argument of type 'any' is not assignable to parameter of type 'string[]'.*/

Note at the last example above: money can't cook you a dish although an implementation signature is the one that implements our function, it cannot be called directly, even though it accepts any as an argument function cookDish(ingredient: any). You can call only overload signatures.

It's dinner time! let's look at a slightly more complex example:

function cookDinner(dish: string): stringfunction cookDinner(money: number): string // Wrong argument type/** This overload signature is not compatible with its implementation signature.*/function cookDinner(dish: string, drink: string, dessert: string): stringfunction cookDinner(dish: string, drink?: string, dessert?: string): string {  let dinner = `${dish}`  if (drink && dessert) {    dinner += ` ${drink}${dessert}`  }  return `${dinner} is ready, bon apptit!`}cookDinner(''); // ' is ready, bon apptit!';cookDinner('', '', ''); // ' is ready, bon apptit!';cookDinner('', '') //  Invalid number of arguments/** No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments.*/

Need to remember that implementation signature must be compatible to overloads and can't be called directly.

Conclusion

Function overloading is a powerful TypeScript feature that allows you to type your functions more elegantly.

More read:

Hope you enjoyed this guide, stay tuned for more.


Original Link: https://dev.to/murashow/quick-guide-to-function-overloading-in-typescript-2178

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To