eduardweb.
TypeScriptIntermediar#typescript#best-practices#web-development

Satisfies vs as vs adnotări explicite: când să nu mai minți compilatorul

De Corina Dobre, 29 apr. 2026 · 2 vizualizări · 2 like-uri

Postat acum 2 zile
typescript
type Color = 'red' | 'green' | 'blue';
type Theme = Record<Color, string>;

// 1. Adnotare (pierdem specificitatea)
const theme1: Theme = { red: '#ff0000', green: '#00ff00', blue: '#0000ff' };
// theme1.red e doar 'string'

// 2. Satisfies (păstrăm valorile exacte)
const theme2 = {
  red: '#ff0000',
  green: '#00ff00',
  blue: '#0000ff'
} satisfies Theme;

// theme2.red e recunoscut ca valoarea specifică '#ff0000'
// Dacă adăugăm o cheie greșită, TS urlă imediat.

Am observat o tendință periculoasă în ultimele luni la review-urile de cod: lumea folosește operatorii de tipare în TypeScript după ureche. Mulți vin din Java sau C# și au instinctul să scrie mereu tipul în stânga, alții s-au obișnuit cu as de pe vremea când TypeScript era mult mai limitat. Adevărul e că, de la versiunea 4.9 încoace, regulile jocului s-au schimbat și mulți scriem cod mai fragil decât e necesar.

Recent, la un proiect unde aveam de gestionat o configurație complexă pentru vreo 12 micro-frontends, am pierdut două ore căutând un bug care nu ar fi trebuit să existe. Totul plecase de la un as pus aiurea care a convins compilatorul că un obiect are niște chei pe care, în realitate, le ștersesem din API.

1. Adnotarea explicită: Safe, dar uneori prea rigidă

Când scrii const user: User = { ... }, îi spui lui TS: „Verifică dacă obiectul ăsta respectă contractul User”. E util la început, dar are o problemă mare: type widening. Dacă ai un tip cu proprietăți opționale sau uniuni, TS va „lărgi” tipul obiectului tău la acea interfață și vei pierde informația specifică pe care o aveai inițial.

Am pățit asta la un sistem de teme (dark/light). Adnotând obiectul cu Record<string, string>, am pierdut auto-complete-ul pentru cheile specifice ca primaryButton. E frustrant să ai tipare și totuși să primești string peste tot în IDE.

2. Operatorul as: Minciuna prin omisiune

Folosesc as doar când chiar nu am de ales, de exemplu la un răspuns de la un API legacy unde n-am chef de validări Zod (greșeala mea, știu). Problema cu as e că e un „type assertion”, nu o verificare. Îi spui compilatorului „Taci, știu eu mai bine”.

La un proiect cu 8k useri activi, am avut un crash în producție pentru că un coleg a folosit as pe un obiect venit dintr-un JSON. Obiectul era parțial gol, dar TypeScript a crezut că e valid. Am învățat atunci lecția: as e pentru teste sau pentru situații extreme, nu pentru business logic de zi cu zi.

3. Operatorul satisfies: Cel mai bun din ambele lumi

Ăsta e game-changer-ul introdus în TS 4.9. Îi spui lui TS: „Verifică dacă obiectul respectă tipul X, dar păstrează inferența cea mai specifică posibilă”.

Dacă ai un obiect cu culori și folosești satisfies, TS te va opri dacă uiți o culoare obligatorie, dar în același timp va ști exact ce string-uri ai folosit ca chei. Nu le transformă într-un string generic. Am economisit cam 30% din timpul de debug la configurări de rute folosind abordarea asta, pentru că IDE-ul îmi zicea exact unde am typo-uri fără să mă oblige să fac cast-uri peste tot.

4. Combo-ul fatal: as const satisfies

Când vrei imutabilitate maximă și validare, ăsta e setup-ul suprem. as const face toate proprietățile readonly și transformă string-urile în literali, iar satisfies se asigură că nu ai uitat nimic din interfață.

Merge de minune pentru obiecte de configurare, mesaje de eroare sau definiții de permisiuni. Trade-off-ul? Codul devine un pic mai dens și s-ar putea ca unii colegi care nu sunt la curent cu ultimele noutăți din TS să se uite ciudat la sintaxă. Dar prefer o întrebare la code review decât un incident la ora 5 după-amiaza.

Voi ce folosiți cel mai des pentru obiectele de configurare? Mai are as loc în codebase-ul vostru în afară de fișierele de test?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.