eduardweb.
TypeScriptÎncepător#typescript#clean-code#web-development

Cum scapi de cod duplicat în TypeScript: Utility Types explicate simplu

De Alexandru Matei, 8 iun. 2026 · 1 vizualizări · 3 like-uri

Postat acum 1 zi
typescript
interface User {
  id: string;
  name: string;
  email: string;
  passwordHash: string;
  role: 'admin' | 'user';
  createdAt: Date;
}

// 1. Pick - extragem doar ce afișăm în listă
type UserPreview = Pick<User, 'id' | 'name' | 'email'>;

// 2. Omit - eliminăm datele sensibile
type PublicProfile = Omit<User, 'passwordHash'>;

// 3. Partial - ideal pentru payload-ul de update (PATCH)
type UpdateUserPayload = Partial<Omit<User, 'id' | 'createdAt'>>;

// Exemplu de funcție care folosește tipul parțial
function updateUser(id: string, data: UpdateUserPayload) {
  // data are acum toate câmpurile opționale (fără id și createdAt)
  console.log(`Updating user ${id} with:`, data);
}

Salutare! Hai să vorbim pe șleau despre TypeScript. Mulți developeri scriu zeci de interfețe aproape identice pentru aceeași entitate, deși limbajul ne oferă unelte excelente ca să evităm copy-paste-ul. Am pățit și eu asta acum câțiva ani la un proiect cu vreo 15k useri activi, unde aveam vreo 5 variante de UserProfile împrăștiate prin cod, până când m-am enervat și am făcut curat folosind utility types.

Folosind corect tipurile astea utilitare, am reușit să eliminăm peste 30% din codul duplicat de tip interfețe. Cel mai important, am scăpat de bug-urile alea enervante când modificai un câmp într-un loc și uitai să-l actualizezi în restul aplicației.

Pick și Omit: Cum decupezi exact ce ai nevoie

Să zicem că ai o interfață uriașă pentru User, care vine direct din baza de date. Conține de toate: id, nume, email, passwordHash, createdAt, updatedAt și roluri.

În frontend, pentru o listă simplă de utilizatori, ai nevoie doar de id, nume și email. În loc să creezi o interfață nouă numită UserShort (pe care o s-o uiți când adaugi câmpuri noi), folosești Pick. El îți permite să extragi doar proprietățile de care ai nevoie dintr-un tip existent.

La polul opus, Omit face exact invers: preia tot, mai puțin cheile pe care le specifici tu. E ideal când vrei să scoți chestii sensibile precum hash-ul parolei înainte de a trimite datele mai departe.

Un trade-off sincer aici: Omit e foarte comod, dar e periculos la refactoring. Dacă schimbi numele unui câmp din baza de date pe care voiai să-l excluzi, TypeScript nu o să urle mereu dacă folosești Omit greșit, pe când la Pick ești mult mai safe fiindcă definești explicit ce vrei să păstrezi.

Partial și Required: Pentru formulare și update-uri

Când faci un endpoint de update (de exemplu, un PATCH request), utilizatorul nu trimite tot obiectul înapoi, ci doar câmpurile pe care le-a modificat. Aici intervine Partial. El transformă toate proprietățile unui tip în proprietăți opționale (le pune un ? la final).

Required face exact opusul: ia un tip care are proprietăți opționale și le transformă pe toate în obligatorii. E util când ai o configurație default și vrei să te asiguri că, după ce ai făcut merge între opțiunile userului și cele default, obiectul final are absolut toate proprietățile completate.

ReturnType: Tipuri dinamice din funcții

Pe asta o folosesc des când lucrez cu funcții de tip factory sau când tipul returnat de o funcție externă e extrem de complex și nu e exportat direct de librărie. ReturnType pur și simplu extrage tipul returnat de o funcție. Te scutește de scris manual tipuri lungi și menține codul sincronizat cu implementarea reală a funcției.

Concluzie și un sfat din tranșee

Utility types sunt geniale pentru a menține codul DRY (Don't Repeat Yourself), dar nu exagerați. Am văzut baze de cod unde trebuia să descifrezi chestii de genul Omit<Partial<Pick<User, 'id' | 'name'>>, 'id'>. Devine imposibil de citit la hover în IDE și îți prinzi urechile în erorile de compilare. Folosiți-le cu cap, doar acolo unde duplicarea chiar aduce un risc real de desincronizare.

Voi ce utility types folosiți cel mai des în proiectele de zi cu zi? Vă limitați la Partial și Omit sau folosiți și chestii mai avansate?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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