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

Cum folosesc Utility Types în TypeScript ca să nu scriu cod duplicat

De Alexandru Matei, 20 iun. 2026 · 18 vizualizări · 3 like-uri

Postat 20 iun. 2026
typescript
interface User {
  id: string;
  name: string;
  email: string;
  passwordHash: string;
  createdAt: Date;
}

// Returnăm doar datele publice în API
type PublicUser = Omit<User, 'passwordHash'>;

// Pentru funcția de update (PATCH), unde luăm doar anumite câmpuri și le facem opționale
type UpdateUserPayload = Partial<Pick<User, 'name' | 'email'>>;

function updateUser(id: string, data: UpdateUserPayload) {
  // data are doar name și email ca opționale
  console.log(`Update user ${id}`, data);
}

Am văzut prea mulți juniori care dublează interfețele în TypeScript doar pentru că o pagină de editare are nevoie de mai puține câmpuri decât tabelul din baza de date. E o pierdere de timp și o sursă garantată de bug-uri de sincronizare. Astăzi vreau să vă arăt cum folosesc eu utilitarele native din TS ca să mențin codul curat și DRY.

La un proiect recent, cu vreo 8.000 de utilizatori activi, aveam o interfață imensă pentru entitatea de User. Avea de toate: de la hash-ul parolei, la token-uri de sesiune și timestamps. Evident, când trimiteam datele către frontend sau când scriam o funcție de update, nu aveam nevoie de tot acel zgomot.

Pick și Omit: Cum decupezi exact ce ai nevoie

Să zicem că ai o interfață mare pentru utilizator. În frontend, pentru un simplu dropdown de selecție, ai nevoie doar de id, name și avatar.

În loc să creezi un tip nou numit UserDropdownItem de la zero, folosești Pick. Îi spui explicit: "ia din User doar cheile astea".

Omit face exact invers. Îl folosesc des când trimit date de la API și vreau să ascund chestii sensibile. De exemplu, vrei să returnezi tot userul, mai puțin parola și token-ul de resetare.

Trade-off-ul sincer aici? Omit e periculos la refactoring. Dacă adaugi un câmp nou sensibil în User peste șase luni, s-ar putea să uiți să-l adaugi în Omit și să-l expui din greșeală în API. De asta, pentru securitate, prefer oricând Pick – e mult mai safe să fii explicit.

Partial și Required: Salvarea noastră la formulare și PATCH-uri

Când făceam un update parțial printr-un endpoint de tip PATCH, m-am lovit de problema trimiterii datelor. Utilizatorul poate modifica doar email-ul, doar numele sau ambele. Aici strălucește Partial. Transformă toate proprietățile unui tip în opționale.

Pe de altă parte, Required face fix opusul. Îl folosesc rar, dar e extrem de util când am o interfață cu câmpuri opționale (cum ar fi configurările unui client), dar într-o anumită funcție de inițializare am nevoie ca absolut toate acele configurări să fie prezente, completate cu valori default.

ReturnType: Când lucrezi cu librării externe

Asta e o bijuterie pe care mulți o ratează. Ai pățit vreodată să folosești o librărie care exportă o funcție complexă de setup, dar nu exportă și tipul returnat de acea funcție?

În loc să încerci să-ți dai seama manual de structura obiectului returnat (și să o rescrii de mână), folosești ReturnType<typeof librarie.setup>. TypeScript își dă seama singur de tipul de date la build time. Am economisit zeci de linii de cod redundant și ore de debugging cu tehnica asta simplă.

Voi ce utilitare folosiți cel mai des în proiectele voastre? Vă limitați la cele de bază sau ați început să vă scrieți propriile tipuri utilitare complexe?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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