Skip to main content

What is function overloading (overload)?

What function overloading (overload) is

Function overloading is the ability to describe several signatures (call variants) of the same function with different argument types and return values.

In simpler terms: a single function can behave differently depending on the types of the arguments.

TypeScript lets you type this through several signatures "on top" and a single implementation "below".


Example 1. A simple overload by argument type

javascript
// Overloads (call variants) function reverse(value: string): string; function reverse(value: number[]): number[]; // Implementation (one for all cases) function reverse(value: string | number[]): string | number[] { if (typeof value === "string") { return value.split("").reverse().join(""); } else { return value.slice().reverse(); } } // Usage examples const str = reverse("TypeScript"); // string const arr = reverse([1, 2, 3]); // number[]

TypeScript understands that:

  • if you pass a string, the function returns string
  • if you pass number[], it returns number[]

How it works

TypeScript sees all the signatures but checks them top to bottom. When it finds a matching one, it applies it. The implementation is not visible to the caller; it only serves to run the code.


Example 2. Different return types

javascript
function toArray(value: string): string[]; function toArray(value: number): number[]; function toArray(value: string | number): (string | number)[] { return [value]; } toArray("hi"); // string[] toArray(42); // number[]

Example 3. A different number of parameters

javascript
function createUser(name: string): { name: string }; function createUser(name: string, age: number): { name: string; age: number }; function createUser(name: string, age?: number) { return age ? { name, age } : { name }; } createUser("Tim"); // { name: string } createUser("Tim", 25); // { name: string; age: number }

Here two signatures describe which combinations of arguments are allowed, and the implementation combines them in a single body.


Example 4. Overloading in generic functions

javascript
function wrap<T>(value: T): { data: T }; function wrap<T>(value: T[]): { data: T[] }; function wrap<T>(value: T | T[]): { data: T | T[] } { return { data: value }; } wrap(42); // { data: number } wrap([1, 2]); // { data: number[] }

How to write overloads correctly

Structure:

javascript
// 1. First: the overload signatures function fn(param: Type1): ReturnType1; function fn(param: Type2): ReturnType2; // 2. Then: the implementation with union types function fn(param: Type1 | Type2): ReturnType1 | ReturnType2 { // logic }

Important: the implementation must always handle all the variants. TypeScript checks that it is compatible with every signature.


Mistakes when overloading incorrectly

You cannot write the implementation before the overload signatures:

javascript
function fn(x: any): any { return x; } // Error: the implementation must come last function fn(x: string): string; function fn(x: number): number;

It must be the other way around:

javascript
function fn(x: string): string; function fn(x: number): number; function fn(x: any): any { return x; }

When to use overloading

Use overloading when:

  • the function has different argument types and different results;
  • this cannot simply be expressed with a union;
  • you need to keep strict typing of the return value.

An alternative to overloading: generics

Sometimes it is simpler to express the same thing through generic types:

javascript
function wrap<T>(value: T): { data: T } { return { data: value }; }

Generic functions are more compact and often preferable when the logic is the same for all types.


Summary cheat sheet

FeatureFunction overloading
Number of implementationsAlways one
Number of signaturesSeveral, on top
Different argumentsYes
Different return typesYes
Order of declarationsSignatures -> implementation
Type checkingTS picks the matching signature
AlternativeGeneric function

An "all together" example

javascript
function format(input: string): string; function format(input: number): string; function format(input: boolean): string; function format(input: string | number | boolean): string { return `Value: ${input.toString()}`; } format("hi"); // string format(123); // string format(true); // string

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.