NoInfer în TypeScript

NoInfer<T> oprește deducerea lui T din acel parametru; T se deduce doar din celelalte argumente.

Sintaxă
function f<T>(valori: T[], implicit: NoInfer<T>): T { ... }

Ce face NoInfer

Când un generic apare în mai mulți parametri, TypeScript îl deduce din toți. Uneori asta este greșit: în alege(["mic", "mare"], "mediu") vrei ca T să fie dedus doar din listă ("mic" | "mare") și ca "mediu" să fie eroare. Fără ajutor, TypeScript lărgește T la "mic" | "mare" | "mediu" și acceptă apelul.

NoInfer<T> marchează locul unde T nu trebuie dedus. Tipul rămâne T, dar argumentul de acolo este doar verificat față de tipul dedus din celelalte. Nu schimbă nimic la rulare și este identic cu T în orice alt context.

Cazuri tipice: valori implicite (implicit: NoInfer<T>), valoarea inițială pentru o listă de opțiuni, callback-uri care nu trebuie să influențeze tipul dedus.

Parametri

Parametru Descriere
T Tipul care trebuie verificat, dar nu dedus, în acea poziție.

Ce returnează

Același tip T.

Exemple

Exemplul 1: Valoare implicită verificată față de listă

function alege<T extends string>(optiuni: T[], implicit: NoInfer<T>): T {
    const ales = process.env.MARIME_INEXISTENTA;
    return optiuni.find((o) => o === ales) ?? implicit;
}

console.log(alege(["mic", "mediu", "mare"], "mediu"));

Rezultat

mediu

Exemplul 2: Fără NoInfer greșeala trece, cu NoInfer este prinsă

În fara, T devine "mic" | "mare" | "mediu" și apelul este acceptat. În cu, T este dedus doar din listă.

function fara<T extends string>(optiuni: T[], implicit: T): T {
    return optiuni[0] ?? implicit;
}
function cu<T extends string>(optiuni: T[], implicit: NoInfer<T>): T {
    return optiuni[0] ?? implicit;
}
const a = fara(["mic", "mare"], "mediu");   // T = "mic" | "mare" | "mediu", fără eroare
const b = cu(["mic", "mare"], "mediu");     // T = "mic" | "mare", "mediu" este eroare
console.log(a, b);

Eroarea afișată de tsc

exemplu.mts(8,31): error TS2345: Argument of type '"mediu"' is not assignable to parameter of type '"mic" | "mare"'.

Greșeli frecvente

  • Pui NoInfer pe toți parametrii. Atunci T nu mai poate fi dedus de nicăieri și devine constrângerea (de exemplu string).
  • Folosești NoInfer cu o versiune TypeScript mai veche de 5.4: tsc dă Cannot find name ‘NoInfer’.

Comenzi înrudite

  • generics (<T>): Parametri de tip: o funcție sau clasă scrisă o dată, care funcționează cu orice tip și păstrează tipul exact.
  • inferența tipurilor: TypeScript deduce singur tipul variabilelor și al rezultatelor din valorile pe care le scrii, fără adnotări.
  • constrângeri generice (extends): T extends Tip limitează tipurile permise pentru T, ca funcția să poată folosi proprietățile lui Tip.
  • tipuri literale: Un tip care acceptă o singură valoare exactă, de exemplu „Iași” sau 3; combinate în union dau liste de valori permise.