eduardweb.
TypeScriptÎncepător#typescript#frontend#javascript#webdev

Utility types în practică: Pick, Omit, Partial, Required și ReturnType

De Cristian Barbu, 30 iul. 2026 · 8 vizualizări · 2 like-uri

Postat 30 iul. 2026
typescript
type User = {
  id: string;
  name: string;
  email: string;
  role: 'admin' | 'user';
  createdAt: Date;
};

// Doar câmpurile necesare pentru cardul de UI
export type UserCardProps = Pick<User, 'name' | 'email'>;

// Payload pentru PATCH /users/:id
export type UpdateUserDTO = Partial<Omit<User, 'id' | 'createdAt'>>;

// Extragere tip din funcție terță
async function createSDKClient() {
  return { apiVersion: 'v2', connect: async () => true };
}

export type SDKClient = Awaited<ReturnType<typeof createSDKClient>>;

Vezi des proiecte unde aceeași entitate e redefinită de 5 ori sub nume diferite? Anul trecut am preluat o aplicație cu peste 45k linii de TypeScript și am găsit 14 tipuri derivate manual din interfața User. Când adăugam un câmp nou, trebuia să modificăm în șapte fișiere diferite.

TypeScript vine din cutie cu un set de utility types care rezolvă fix problema asta. Dacă le folosești corect, scapi de duplicare și faci codebase-ul mult mai ușor de întreținut.

Pick și Omit: când vrei doar o bucată din interfață

Cele mai folosite sunt Pick și Omit. Numele le descrie exact funcția: Pick păstrează doar cheile pe care i le ceri, iar Omit le scoate afară pe cele menționate.

La un proiect e-commerce cu vreo 8k useri activi, aveam o problemă simplă: componenta de profil avea nevoie doar de name și avatarUrl dintr-un obiect masiv UserProfile de 25 de câmpuri. În loc să facem o nouă interfață UserProfileCardProps, am folosit Pick<UserProfile, 'name' | 'avatarUrl'>.

Trade-off-ul sincer? Omit e un cuțit cu două tăișuri. Dacă folosești Omit<User, 'password'> și mai târziu redenumești password în hashedPassword în interfața principală, Omit-ul tău nu va mai scoate noul câmp fără ca compiler-ul să te avertizeze explicit. Unde se poate, prefer Pick pentru că e mai strict: dacă schimbi denumirea proprietății, primești eroare imediat.

Partial și Required: manipularea opționalității

Când faci un API endpoint de tip PATCH, de obicei clientul trimite doar câmpurile pe care vrea să le modifice. Aici intră în scenă Partial<T>, care face toate proprietățile opționale.

Required<T> face exact opusul: scoate opționalitatea de pe toate câmpurile. Eu îl folosesc des la opțiuni de configurare unde utilizatorul poate trimite un obiect parțial, dar intern în aplicație aplic valori default și am nevoie ca starea finală să fie completă.

Atenție însă cu Partial: e foarte tentant să-l arunci peste tot în componente de React sau în store-uri. Dacă abuzezi de el, te trezești că trebuie să pui optional chaining (?.) și verificări de undefined în tot codul, anulând beneficiile pe care ți le oferă TypeScript.

ReturnType: când biblioteca terță nu exportă tipurile

Mi s-a întâmplat de zeci de ori: instalez un pachet din npm, folosesc o funcție de factory complexă, dar autorul bibliotecii a uitat să exporte tipul obiectului returnat.

În loc să scriu eu manual tipul prin copy-paste din node_modules (o rețetă sigură pentru dezastru la următorul npm update), folosesc ReturnType<typeof numeFunctie>. Combini asta cu Awaited dacă funcția e asincronă și ai extras tipul exact pe care îl returnează funcția respectivă.

Voi ce utility types folosiți cel mai des în producție? Mai scrieți tipuri derivate de mână sau vă bazați pe generics de genul ăsta?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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