Typescript method overloading

Image for post
Image for post

Method overloading is a familiar concept from traditional programming languages like Java or C#. It allows a class to have multiple methods with the same name if their signature is different.

But Typescript only helps us during edit and compile time and not at runtime. Therefore method overloading works differently. The executed code is still pure Javascript.

Due to the dynamic nature of JavaScript, we can’t use overloading in the same way we do in other languages. Let’s have a look at JavaScript’s function parameter rules: ☝️

- JavaScript function definitions do not specify data types for parameters.

- JavaScript functions do not perform type checking on the passed arguments.

- JavaScript functions do not check the number of arguments received.

The third rule is especially interesting in the context of method overloading. Let’s have a closer look.

The code above is valid and doesn’t produce an error even if we pass more arguments than required or also if we don’t pass any arguments at all.

Missing parameters will result in undefined; additional parameters will be accessible in an “arguments” object.

Follow me on Twitter or medium to get notified about the newest blog posts and interesting frontend stuff!🐤

Of course, Typescript will complain in the scenarios above. But remember this is only during edit and compile time, not at runtime.

Illustrating the problem 🕵🏼

Let’s keep that in mind and have a look at a concrete example where we want to use overloading with typescript. Let’s imagine we have the following service:

and the corresponding component:

The Typescript compiler warns us about a bunch of things. Nevertheless, the application starts. So let’s inspect the code that is executed.

If the user enters a name and no skill, we would expect getHero(name: string) to be called. But guess what happens? We always enter our breakpoint in getHero(name: string, skill: string).

How come? Again, during execution time it’s not Typescript that runs, its Javascript. And Javascript only sees the method that was defined last. It then passes only one parameter, the “heroname” to this method. But remember what happens to the second parameter?

Right, due to Javascript’s nature it is undefined. So how can we fix this? 🤔

Optional parameters or function declarations

We can easily solve this problem by making the skills parameter optional and add some parameter checks. With this adjustment, we only have one function.

Based on the function signature Typescript provides us the following parameter hints.

That’s cool! But there’s also another possibility to achieve the same method overloading with different intellisense. Let’s add overloads for the getHero method.

Click here to tweet about this article 🐥

public getHero(name: string);
public getHero(name: string, skill: string);

Notice that we still have the function that gets executed at runtime and we still need the parameter checks. This code does the same as the previous but the intellisense is different.

Depending on your tslint settings Typescript will complain that those methods can be combined into one signature with an optional parameter. If you want to use this syntax and disable the warning, you can add the following line to your tslint.json.

“function declarations” just improved intellisense or more?

As mentioned above the function declaration improves the intellisense. But is there an additional benefit over the optional parameters approach?

Indeed there are other scenarios where the helper methods might be helpful. Imagine you have the following code:

This function accepts a number or an Observable as the first parameter and a filter function as the second parameter.

Having a filter function only makes sense when the first value is an Observable. With the code above we could easily call the function in the following way without Typescript complaining about it.

With the help of function declaration, we can express that we only allow a filter function in combination with an Observable. So if we add the following two signatures:

Typescript will now complain when we try to call foo with a number and a filter function. This saves us some unnecessary runtime checks.

Conclusion

Method overloading in Typescript differs from traditional programming languages like Java or C#.

To overload methods, you can either choose optional parameters or function declarations.

In general, Typescript is capable to help us during edit and compile time but always keep in mind that the executed code is just Javascript and may require some checks.

In some scenarios function declarations allow you to express the desired parameter combination and therefore may save you the runtime checks.

🧞‍ 🙏 Give some 👏🏻 by clicking multiple times on the button on the left side if you enjoyed this post.

Claps help other people finding it and encourage me to write more posts

Feel free to check out some of my other articles about frontend development.

Written by

Passionate freelance frontend engineer. ❤️ Always eager to learn, share and expand knowledge.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store