Skip to content

Function overload

Daisho Komiyama edited this page Apr 3, 2022 · 1 revision

Problem

When a function does more than one thing, we tend to write a union-type return value.

However, the TypeScript compiler can't wrap its head around it.

Look at this case. We get a few complaints.

function add(a: number, b?: number): number | ((b: number) => number) {
  if (b !== undefined) {
    return a + b
  } else {
    return (b: number) => a + b
  }
}

add(2,3)
const addTwo = add(2) // This expression is not callable. Not all constituents of type 'number | ((b: number) => number)' are callable.
const twentyTwo = addTwo(20)
const seventeen = add(8)(9) // This expression is not callable. Not all constituents of type 'number | ((n: number) => number)' are callable.

It seems setting a union-type return value doesn't help. Function overload helps.

Function overload

Write a function overload to solve this problem. Add two function signatures right above the declaration.

First signature covers the number and the second covers (b: number) => number in number | ((b: number) => number) union-type.

function add(a: number, b: number): number;
function add(a: number): (b: number) => number;
function add(a: number, b?: number) {
  if (b !== undefined) {
    return a + b
  } else {
    return (b: number) => a + b
  }
}

add(2,3)
const addTwo = add(2)
const twentyTwo = addTwo(20)
const seventeen = add(8)(9)
// No complaint!

One caveat is that we probably have to use function declarations, not arrow functions. I've tried a suggested solution for arrow functions, but it never worked for me.

Clone this wiki locally