eduardweb.
TypeScriptIntermediar#typescript#frontend#clean-code#best-practices

Satisfies, as sau Explicit? Cum scapi de erori fără să pierzi DX

De George Iliescu, 1 mai 2026 · 1 vizualizări · 3 like-uri

Postat acum 2 zile
typescript
type Colors = "primary" | "secondary";
type Theme = Record<Colors, string | { r: number, g: number, b: number }>;

// CAZUL 1: Explicit - Pierdem info despre structura specifică
const theme1: Theme = {
  primary: "#ff0000",
  secondary: { r: 0, g: 255, b: 0 }
};
// theme1.secondary.r -> EROARE: Property 'r' does not exist on type 'string | { r... }'

// CAZUL 2: satisfies - Validăm tipul, dar păstrăm specificitatea
const theme2 = {
  primary: "#ff0000",
  secondary: { r: 0, g: 255, b: 0 }
} satisfies Theme;

console.log(theme2.secondary.r); // MERGE! TS știe că e obiect, nu string

Am observat în ultimele luni o confuzie generalizată în PR-uri legată de cum definim tipurile în TypeScript. Mulți colegi vin din Java sau C# și au tendința să pună tipuri explicite peste tot, în timp ce alții, mai leneși, trântesc un as AnyType doar ca să tacă compilerul și să dea push la cod. Ambele abordări au hibele lor, iar de când a apărut satisfies în versiunea 4.9, regulile jocului s-au schimbat destul de mult.

La un proiect recent cu peste 120 de componente în React, am făcut un refactoring masiv pe partea de config-uri. Am eliminat vreo 40 de type assertions și am trecut pe satisfies. Rezultatul? Am prins 3 bug-uri de logică pe care unit testele le rataseră pentru că tipurile erau „forțate” incorect.

1. Tiparea explicită (The Classic Way)

Când scrii const user: User = { ... }, îi spui compilatorului că obiectul trebuie să respecte exact acea interfață. E sfântă pentru contracte de API sau când vrei să fii sigur că nu uiți un field obligatoriu.

Totuși, are un mare dezavantaj: pierzi specificitatea. Dacă ai un obiect de configurare unde cheile pot fi orice string, dar tu știi exact ce chei ai scris, tiparea explicită cu un Index Signature (Record<string, any>) te lasă în ceață. TypeScript nu mai știe că config.theme există, el vede doar un string generic. E frustrant să pierzi autocompletion-ul doar pentru că ai vrut să fii „corect”.

2. Type Assertion (as) - Operatorul „crede-mă pe cuvânt”

Folosesc as doar când chiar n-am altă soluție, de exemplu la interacțiunea cu librării externe prost tipate sau la rezultate de tip any din JSON.parse. În rest, e periculos.

Am pățit-o la un sistem de permissions: cineva a pus as Permission[] pe un array care venea de fapt gol sau cu null de la un API. Codul a compilat brici, dar în runtime totul a crăpat cu un „cannot read property of undefined”. as îi spune compilatorului: „Știu eu mai bine, taci”. De cele mai multe ori, nu știm mai bine.

3. Operatorul satisfies (The Sweet Spot)

Acesta e motivul pentru care scriu postarea asta. satisfies verifică dacă un obiect respectă o interfață, dar îi permite compilatorului să păstreze cel mai specific tip posibil pentru acel obiect.

E genial pentru teme, rute de navigare sau configurații de chart-uri. Dacă ai un obiect colors și folosești satisfies Record<string, string>, TypeScript va valida că toate valorile sunt string-uri, dar dacă scrii colors.primary, va ști exact că e culoarea ta specifică, nu un string random. Am economisit cam 20% din timpul de debugging la CSS-in-JS folosind chestia asta.

4. Când alegi ce? (Quick Guide)

  • Contracte de API / Date primite: Folosește tipare explicită sau validare cu Zod. Vrei să știi clar dacă datele nu respectă schema.
  • Configurații interne / Obiecte literale: Mergi pe satisfies. Primești validare, dar păstrezi și inference-ul puternic pentru restul aplicației.
  • Librării legacy / DOM API: Aici as rămâne rege, dar cu moderație. Dacă poți folosi un Type Guard în loc de as, fă-o.
  • Funcții scurte: Lasă TypeScript să facă inference singur. Nu e nevoie să scrii tipul returnat dacă e evident din cod.

Trade-off-ul e simplu: vrei siguranță rigidă (Explicit) sau vrei flexibilitate verificată (Satisfies)? Eu înclin spre a doua variantă în 80% din cazurile de frontend development modern.

Voi ce folosiți cel mai des pentru obiectele de config? Mai are loc as în codebase-ul vostru?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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