DEV Community

Gaëtan Redin
Gaëtan Redin

Posted on • Originally published at Medium on

TypeScript Function Overloads

When to use TypeScript Function Overloads

I have to admit that I found out about this feature recently. But I would like to share it with you because I find it really easy to understand and simplify code. But like all features, it has its own use cases, and sometimes we should not use this syntax.

When Should We Use TypeScript Function Overloads

Suppose you have two ways to get a user – by its id, which is a number – or by its name (string), first name (string), and birthdate (Luçon DateTime).

Here we have the same method with different parameters.

A first approach could be:

function getUser(idOrName: string | number, firstName?: string, birthDate?: DateTime): User {
  ...
}
Enter fullscreen mode Exit fullscreen mode

But it’s not really relevant because it means that we could also use it like this:

getUser(name, firstName);
Enter fullscreen mode Exit fullscreen mode

And that’s not what we expected to write.

We only want to can do:

getUser(id);
getUser(name, firstName, birthDate);
Enter fullscreen mode Exit fullscreen mode

So this is how to implement what we expect:

getUser(id: number): User; // (1)
getUser(name: string, firstName: string, birthDate: DateTime): User; // (2)
getUser(idOrName: string | number, firstName?: string, birthDate: DateTime): User {
  if(typeof idOrName === number) {
    (1)
  } else {
    // (2)
  }
}
Enter fullscreen mode Exit fullscreen mode

Rules:

  • The implementation must handle all cases.
  • The implementation signature must be the last.

When Should We Not Use TypeScript Function Overloads

Suppose now we have an interface Identity that contains name, first name, and birthDate. It could be tempting to write this:

interface Identity {
  name: string;
  firstName: string;
  birthDate: DateTime;
}

getUser(id: number): User;
getUser(identity: Identity): User;
getUser(idOrIdentity: number | Identity): User {
  ...
}
Enter fullscreen mode Exit fullscreen mode

But that’s not the simplest way to code this. That’s better:

interface Identity {
  name: string;
  firstName: string;
  birthDate: DateTime;
}

getUser(idOrIdentity: number | Identity): User {
  ...
}
Enter fullscreen mode Exit fullscreen mode

You should always prefer the union type when it’s possible. This is a Typescript recommendation, and as you can see, it’s more simple.

Remember that function overload is useful when you don’t have the same number of parameters.

Thanks for reading.

Learn More

Discussion (0)