overload în TypeScript

Funcții TypeScript 1.0

Mai multe semnături pentru aceeași funcție, ca rezultatul să aibă tipul potrivit pentru fiecare fel de apel.

Sintaxă
function f(x: string): string;
function f(x: number): number;
function f(x: string | number): string | number {
    // implementarea
}

Ce face overload

Uneori tipul rezultatului depinde de tipul argumentului: pentru un text returnezi text, pentru un număr returnezi număr. Cu un singur union ((x: string | number): string | number), apelantul primește mereu union-ul și trebuie să verifice. Overload-urile rezolvă asta: scrii mai multe semnături fără corp, apoi o singură implementare.

Doar semnăturile de deasupra se văd din afară; semnătura implementării nu poate fi apelată direct. Implementarea trebuie să fie compatibilă cu toate semnăturile, iar TypeScript alege prima semnătură care se potrivește cu apelul, deci ordinea contează: pune variantele specifice înaintea celor generale.

Dacă variantele diferă doar prin tip și rezultatul se poate exprima cu un tip generic sau un union, preferă-le: sunt mai simple. Overload-urile și metodele claselor funcționează la fel.

Exemple

Exemplul 1: Rezultat de tip diferit după argument

function dublu(x: string): string;
function dublu(x: number): number;
function dublu(x: string | number): string | number {
    return typeof x === "string" ? x + x : x * 2;
}

const a = dublu("ha");   // string
const b = dublu(21);     // number
console.log(a.toUpperCase(), b.toFixed(1));

Rezultat

HAHA 42.0

Exemplul 2: Număr diferit de parametri

data(timestamp) sau data(an, luna, zi). Un apel cu două argumente nu se potrivește cu nicio semnătură.

function data(timestamp: number): Date;
function data(an: number, luna: number, zi: number): Date;
function data(a: number, luna?: number, zi?: number): Date {
    return luna !== undefined && zi !== undefined ? new Date(Date.UTC(a, luna - 1, zi)) : new Date(a);
}

console.log(data(0).toISOString());
console.log(data(2026, 10, 19).toISOString().slice(0, 10));

Rezultat

1970-01-01T00:00:00.000Z
2026-10-19

Exemplul 3: Semnătura implementării nu se vede din afară

function dublu(x: string): string;
function dublu(x: number): number;
function dublu(x: string | number): string | number {
    return typeof x === "string" ? x + x : x * 2;
}
const v: string | number = Math.random() > 0.5 ? "a" : 1;
console.log(dublu(v));

Eroarea afișată de tsc

exemplu.mts(7,19): error TS2769: No overload matches this call.
  Overload 1 of 2, '(x: string): string', gave the following error.
    Argument of type 'string | number' is not assignable to parameter of type 'string'.
      Type 'number' is not assignable to type 'string'.
  Overload 2 of 2, '(x: number): number', gave the following error.
    Argument of type 'string | number' is not assignable to parameter of type 'number'.
      Type 'string' is not assignable to type 'number'.

Greșeli frecvente

  • Te aștepți ca semnătura implementării să fie una dintre variante. Nu este; dacă vrei să accepți și union-ul, adaugă o semnătură (x: string | number): string | number.
  • Pui semnătura generală prima. TypeScript o alege mereu și variantele specifice nu mai sunt folosite.

Comenzi înrudite

  • funcții cu tipuri: Pui tipuri pe parametrii și pe rezultatul funcțiilor; fiecare apel este verificat la compilare.
  • generics (<T>): Parametri de tip: o funcție sau clasă scrisă o dată, care funcționează cu orice tip și păstrează tipul exact.
  • union (|): Un tip care acceptă valori din mai multe tipuri: A | B înseamnă fie A, fie B.
  • conditional types: Un tip care alege între două variante după o condiție: T extends U ? X : Y.