inferența tipurilor în TypeScript

Tipuri de bază TypeScript 1.0

TypeScript deduce singur tipul variabilelor și al rezultatelor din valorile pe care le scrii, fără adnotări.

Sintaxă
let x = 5;                 // x: number
const y = "Iași";          // y: "Iași"
const f = (a: number) => a * 2;   // returnează number

Ce face inferența tipurilor

Nu trebuie să scrii tipul peste tot. Când declari o variabilă cu o valoare, TypeScript se uită la valoare și deduce tipul: let x = 5 devine number, let nume = "Ana" devine string. La fel deduce tipul returnat de o funcție, tipul elementelor dintr-un tablou și tipul proprietăților unui obiect.

La let tipul dedus este cel general (string), pentru că variabila se poate schimba. La const cu o valoare simplă, tipul este chiar valoarea (tipul literal "Iași"), pentru că nu se mai poate schimba. Pentru un tablou cu elemente diferite, tipul dedus este un union: [1, "a"] devine (string | number)[].

Regula practică: lasă inferența să lucreze pentru variabilele locale și scrie tipurile explicit la parametrii funcțiilor, la datele exportate și acolo unde vrei ca o greșeală să fie prinsă devreme. Parametrii fără tip sunt o eroare în modul strict (noImplicitAny).

Exemple

Exemplul 1: Tipuri deduse din valori

Niciun tip nu este scris, dar toate sunt cunoscute. typeof din JavaScript afișează tipul valorii la rulare.

let nume = "Ana";                 // string
let note = [9, 10, 8];            // number[]
const elev = { nume, oras: "Iași", note };   // { nume: string; oras: string; note: number[] }

const medie = (lista: number[]) => lista.reduce((s, n) => s + n, 0) / lista.length;   // returnează number

console.log(typeof nume, Array.isArray(note), typeof elev.oras);
console.log(medie(elev.note).toFixed(2));

Rezultat

string true string
9.00

Exemplul 2: let deduce tipul general, const valoarea exactă

Variabila a are tipul string, iar b are tipul literal "Cluj". De aceea b se poate da unei funcții care acceptă doar anumite orașe, iar a nu.

type Oras = "Iași" | "Cluj" | "Timișoara";
function trimite(oras: Oras) {
    console.log("Trimis la", oras);
}

let a = "Cluj";
const b = "Cluj";
trimite(b);   // corect: b are tipul "Cluj"
trimite(a);   // eroare: a are tipul string

Eroarea afișată de tsc

exemplu.mts(9,9): error TS2345: Argument of type 'string' is not assignable to parameter of type 'Oras'.

Exemplul 3: Tipul dedus nu se mai schimbă

Inferența are loc o singură dată, la declarare. După aceea variabila acceptă doar valori de același tip.

let scor = 10;
scor = "zece";
console.log(scor);

Eroarea afișată de tsc

exemplu.mts(2,1): error TS2322: Type 'string' is not assignable to type 'number'.

Greșeli frecvente

  • Declari un tablou gol, const lista = [], și te aștepți la un tip anume. Scrie tipul: const lista: string[] = [].
  • Adaugi adnotări inutile peste tot (const x: number = 5). Nu greșești, dar codul devine mai lung fără să câștigi siguranță.
  • Uiți că un parametru de funcție nu se deduce din apeluri. Fără tip, în modul strict primești eroarea Parameter ‘x’ implicitly has an ‘any’ type.

Comenzi înrudite

  • let și const cu tipuri: Declari variabile cu let (se pot schimba) sau const (nu se pot reatribui) și le pui tipul după două puncte.
  • tipuri literale: Un tip care acceptă o singură valoare exactă, de exemplu „Iași” sau 3; combinate în union dau liste de valori permise.
  • any: Tipul care oprește verificarea: o valoare any acceptă orice și poate fi folosită oricum, fără erori de compilare.
  • as const: Face un literal complet readonly și păstrează valorile exacte ca tipuri: „Iași” în loc de string.