Skip to main content

Function Overloads

Sometimes a function can be called in multiple different ways, returning entirely different types based on the arguments provided.

The problem

Imagine a function that takes either a string or an array. If you pass a string, it returns a string. If you pass an array, it returns an array.

function reverse(input: string | any[]): string | any[] {
if (typeof input === "string") return input.split("").reverse().join("");
return input.slice().reverse();
}

const res = reverse("hello");
// res is typed as 'string | any[]'. We lost the specificity!

Even though we passed a string, TypeScript doesn't know the correlation between the input type and the output type.

The solution: Overload signatures

Function overloads let you declare multiple signatures for a single function. You write the specific signatures first, followed by a final, wider implementation signature.

// 1. Overload signatures (what the consumer sees)
function reverse(input: string): string;
function reverse(input: any[]): any[];

// 2. Implementation signature (what the compiler checks against)
function reverse(input: string | any[]): string | any[] {
if (typeof input === "string") {
return input.split("").reverse().join("");
}
return input.slice().reverse();
}

const strRes = reverse("hello"); // Valid: Typed exactly as 'string'
const arrRes = reverse([1, 2, 3]); // Valid: Typed exactly as 'any[]'

The implementation signature is hidden

A crucial detail: the implementation signature (string | any[]) is invisible to the outside world. If a consumer tries to call reverse with a union type string | any[], it will actually fail, because neither of the two specific overload signatures match a union.

Overloads should only be used when the return type fundamentally changes based on the arguments. For minor variations, optional parameters or simple Generics are better.

Function overloads allow you to create tightly correlated input-to-output type signatures. Write the specific public signatures first, and the wide implementation signature last.