Different return types for same function in Typescript
Tags: javascript, webdev, typescript
Published: 2020-10-04 20:09:31

# Also known as overloaded functions

The idea is that you have a function that accepts different arguments or argument types. And based on what arguments you pass you can have different return types. 

## The example
This could be used in several ways, as everything, but we will keep it simple (example simple). And get rid of one of those annoying things that typescript cant understand. Look at this function: 

```typescript
function greet(user:IUser | undefined):string | undefined {
  if(!user) return undefined;
  return `Hello ${user.firstName} ${user.lastName}!`
}
```
We know for sure that when the user is defined we will get the string.  Could we tell Typescript this? The short answer is **yes**!

### And here is how
As said, we will overload our function and you can find [more info here in the docs](https://www.typescriptlang.org/docs/handbook/functions.html#overloads).

The syntax might look a bit weird, at least in my opinion. But we can tell Typescript all the different ways we can call the function and what return type is associated with them. Like this:

```typescript
function greet(user: IUser):string
function greet(user: IUser | undefined):string | undefined
```
This is our "overloads" of the function that we add before the actual implementation. Now the function looks like this:

```typescript
function greet(user: IUser):string
function greet(user: IUser | undefined):string | undefined
function greet(user: IUser | undefined):string | undefined {
  if(!user) return undefined;
  return `Hello ${user.firstName} ${user.lastName}!`
}
```

Or you could just type the actual function with `any`, that is fine too:

```typescript
function greet(user: IUser):string
function greet(user: IUser | undefined):string | undefined
function greet(user: any):any {
  if(!user) return undefined;
  return `Hello ${user.firstName} ${user.lastName}!`
}
```

Now Typescript is aware that when we have a user we *will* get a string, and when we might have a user. Well we might get a string. 

And if you go with the `any` way of method implementation, you still cannot call the function with `any` argument. It will have to be `IUser` or `undefined`. 

[You can check the example here](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgJIFUDO1kG8BQyRyMwUmYAcnALYQBcyFUoA5gNyHEA2cF1dRszacAvvnwwAriARhgAexDJWUCBDAAKKdiiMMugJT1hIVpJlzFy1eq07o+rDgA+yGQBMIpEBA-GmMBYzZDdPb1A-C1l5JRU1DW1dRjgQAE9jVLS8LiJgGE0AQgcoQ2Q1MCkoZXCfP05ico0q5QADABJcEoA6UnIqWghRZABaZE6e3n5B0Vb8cXxuDXdktGcoUPcQLzqPTnwEJQpkOkxMOFYIAH0YBSgrzCqUAF54u01cPunBZAAiAGVgDQlL8ADTIKYDH4AoIAN5ov1EhgORzAJwgZwu1xocDSACMXm9EiVkYcQMcwAALYCYK4Ad2A3G4VxACjA9LuAGtkK9bIkAIwAJgAzMigA)

## Summary
Yes, this example is a little bit simple. But the idea is that the when we call the function we can be made aware when we need to check for `undefined` and when we can skip. 

It will make the code easier for your colleagues, or future you, to approach. The functions in "real life" will probably be more complex and by giving the return type for different options will make the life easier for everyone. By not having to read the function details to understand when we get type **x** and when we get type **y**.  

Cover photo by Juan Gomez [Unspash](https://unsplash.com/photos/kt-wA0GDFq8)