← Back to TypeScript Course | Chapter 3: Variables and Functions | Lesson 10 of 10

Function Overloading

Function overloading allows TypeScript to describe multiple valid ways to call the same function. Each overload provides a different call signature while a single implementation handles the actual logic.
Syntax
typescript
function name(param: type1): returnType1;
function name(param: type2): returnType2;
function name(param: any): any {
  // implementation
}

Basic Function Overloads

Function overloading starts by writing multiple overload signatures, each describing one valid combination of parameter types, directly above a single shared implementation signature.

Callers only ever see and choose from the overload signatures, never the implementation's own signature.

Example: Basic Function Overloads

typescript
function format(value: string): string;
function format(value: number): string;
function format(value: string | number): string {
  return `Value: ${value}`;
}
console.log(format("hi"), format(5));

Overloading with Different Parameters

Overload signatures can describe functions that accept entirely different numbers or combinations of parameters, such as one overload taking a single string and another taking a string plus a number.

TypeScript picks the matching overload based on how the function is actually called.

Example: Overloading with Different Parameters

typescript
function combine(a: string): string;
function combine(a: string, b: number): string;
function combine(a: string, b?: number): string {
  return b === undefined ? a : `${a}-${b}`;
}
console.log(combine("id"), combine("id", 42));

Overload Implementation

The implementation signature underneath all the overloads must be broad enough in its own types to satisfy every overload's promises, even though callers never call that signature directly.

This is what lets a single function body correctly handle every declared overload case.

Example: Overload Implementation

typescript
function toArray(value: string): string[];
function toArray(value: number): number[];
function toArray(value: string | number): (string | number)[] {
  return [value];
}
console.log(toArray("x"), toArray(1));

Overloads and Return Types

Different overloads are free to specify different return types depending on which input pattern was matched, letting the compiler give callers a precisely typed result instead of one overly broad union type.

This is one of overloading's biggest practical benefits.

Example: Overloads and Return Types

typescript
function parseValue(value: string): number;
function parseValue(value: number): string;
function parseValue(value: string | number): number | string {
  return typeof value === "string" ? Number(value) : String(value);
}
console.log(parseValue("42"), parseValue(42));

When to Use Function Overloading

Reach for function overloading when a single function naturally supports several distinct, well-defined input patterns and you want TypeScript to give callers precise, pattern-specific type checking.

For simpler cases, a single signature using union types or optional parameters is usually easier to maintain.

Example: When to Use Function Overloading

typescript
function makeDate(timestamp: number): Date;
function makeDate(year: number, month: number, day: number): Date;
function makeDate(a: number, b?: number, c?: number): Date {
  return b === undefined ? new Date(a) : new Date(a, b, c);
}
console.log(makeDate(2024, 0, 1));
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Writing only the overload signatures and forgetting the single implementation below them.
  2. Making the implementation signature too narrow, so it does not match all the overloads.
  3. Expecting the implementation signature to be callable, when only the overload signatures are visible to callers.
Chapter Summary
  • Use let and const with type annotations, and let type inference work out types when they are obvious.
  • Functions can type their parameters and return values, and support optional, default, and rest parameters.
  • Arrow functions and function overloading let you describe flexible function signatures with precise types.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.