Ce face interface vs type
Pentru a descrie forma unui obiect, interface și type fac aproape același lucru și se pot combina între ele. Diferențele: doar type poate numi union-uri, tuple-uri, primitive și tipuri calculate (mapped, conditional). Doar interface se poate redeclara ca să primească proprietăți noi (declaration merging), lucru folosit la extinderea tipurilor globale, de exemplu Window.
Moștenirea se scrie diferit: interface B extends A față de type D = C & {...}. Când proprietățile se contrazic, extends dă o eroare clară la declarare, iar & produce în tăcere o proprietate de tip never. Mesajele de eroare cu interfețe sunt de obicei mai scurte, pentru că tsc afișează numele interfeței.
Recomandarea din documentația TypeScript: folosește interface pentru obiecte și clase până ai nevoie de ceva ce doar type poate face; folosește type pentru union-uri, funcții și tipuri calculate. Cel mai important este să fii consecvent în proiect.
Exemple
Exemplul 1: Același obiect, descris în ambele feluri
interface ElevI {
nume: string;
nota: number;
}
type ElevT = {
nume: string;
nota: number;
};
const a: ElevI = { nume: "Ana", nota: 9 };
const b: ElevT = a; // compatibile: aceeași formă
const c: ElevI = b;
console.log(a, b === c);
Rezultat
{ nume: 'Ana', nota: 9 } true
Exemplul 2: Ce poate doar type, ce poate doar interface
Raspuns este un union (imposibil cu interface). Cele două declarații Setari se unesc într-una singură (imposibil cu type).
type Raspuns = { ok: true; date: string } | { ok: false; eroare: string };
interface Setari {
limba: string;
}
interface Setari {
tema: "luminoasă" | "întunecată";
}
function text(r: Raspuns): string {
return r.ok ? r.date : `eroare: ${r.eroare}`;
}
const s: Setari = { limba: "ro", tema: "întunecată" };
console.log(s);
console.log(text({ ok: true, date: "10 elevi" }));
console.log(text({ ok: false, eroare: "fără conexiune" }));
Rezultat
{ limba: 'ro', tema: 'întunecată' }
10 elevi
eroare: fără conexiune
Exemplul 3: Conflict de proprietăți: extends dă eroare
Cu type X = A & { id: string }, proprietatea id ar deveni never fără nicio eroare la declarare. Cu interface ... extends, conflictul este semnalat imediat.
interface A {
id: number;
}
interface B extends A {
id: string;
}
const b: B = { id: "x" };
console.log(b);
Eroarea afișată de tsc
exemplu.mts(4,11): error TS2430: Interface 'B' incorrectly extends interface 'A'.
Types of property 'id' are incompatible.
Type 'string' is not assignable to type 'number'.
Greșeli frecvente
- Amesteci la întâmplare interfețe și aliasuri pentru același fel de date. Alege o regulă pentru proiect.
- Folosești
&între tipuri cu aceeași proprietate de tipuri diferite și primești o proprietatenevergreu de înțeles.
Comenzi înrudite
interface: Descrie forma unui obiect: ce proprietăți are, de ce tip sunt și ce metode are.type (alias de tip): Dă un nume oricărui tip: obiect, union, tuple, funcție sau un tip calculat din alte tipuri.intersection (&): Combină mai multe tipuri într-unul: A & B are toate proprietățile lui A și toate proprietățile lui B.union (|): Un tip care acceptă valori din mai multe tipuri: A | B înseamnă fie A, fie B.extends: O clasă moștenește câmpurile și metodele altei clase; o interfață preia proprietățile altor interfețe.