eduardweb.
TypeScript avansatAvansat#architecture#typescript#type-safety

Cum am mapat permisiunile fără să înnebunesc: Template Literal Types în TypeScript

De Adrian Voicu, 14 iun. 2026 · 15 vizualizări · 3 like-uri

Postat 14 iun. 2026
typescript
type Resource = 'user' | 'billing' | 'report';
type Action = 'create' | 'read' | 'update' | 'delete';

// TS generează automat tipul:
// "api:user:create" | "api:user:read" | ... | "api:billing:delete"
type Permission = `api:${Resource}:${Action}`;

interface User {
  id: string;
  permissions: Permission[];
}

function hasAccess(user: User, required: Permission): boolean {
  return user.permissions.includes(required);
}

// TypeScript va urla aici pentru că 'biling' are un typo:
// hasAccess(currentUser, 'api:biling:read');

Salutare! Am avut acum ceva timp de făcut un refactoring pe un sistem de permisiuni la un proiect destul de măricel, cu vreo 80 de endpoint-uri și roluri dinamice. Clasic, aveam în bază stringuri gen user:write, report:read sau billing:delete. Problema a fost că la un moment dat un coleg a trimis din greșeală biling:write (cu un singur „l”) într-un middleware, codul a trecut de teste, a ajuns în producție și ne-am trezit că unii clienți nu-și mai puteau plăti abonamentele.

Atunci mi-am zis că trebuie să legăm permisiunile astea direct de tipurile din TypeScript. Nu voiam un enum uriaș pe care să-l tot extindem manual de fiecare dată când mai adăugăm o resursă în aplicație. Așa că am apelat la template literal types.

Cum funcționează magia în TypeScript

Practic, template literal types îți permit să folosești sintaxa de template strings de la nivel de valoare direct la nivel de tip. TypeScript generează automat toate combinațiile posibile. E un produs cartezian rulat direct de compilator.

Dacă ai o mână de resurse și câteva acțiuni standard, definirea lor e extrem de curată. Compilatorul va genera automat uniunea tuturor permutărilor. Partea mișto e că primești autocomplete instant în IDE. Când începi să scrii stringul, editorul îți arată exact ce resurse ai disponibile și ce acțiuni poți să le aplici. Nu mai există șansa să scrii greșit vreun caracter.

Trade-off-ul sincer: compiler performance

Sună ideal, dar există o capcană majoră de care m-am lovit destul de repede. Dacă ai 50 de resurse și 10 acțiuni, TypeScript va genera 500 de tipuri unice în spate. Asta e floare la ureche pentru compilator. Dar dacă începi să imbrici template-urile, de exemplu api:${Role}:${Resource}:${Action}:${Scope}, numărul de combinații explodează exponențial.

La un alt proiect unde am exagerat cu chestia asta, build time-ul pe CI a crescut cu aproape 40 de secunde și VS Code începuse să agațe când dădeam hover pe tipuri. Ba chiar am dat de celebra eroare: Expression produces a union type that is too complex to represent.

Sfatul meu: folosește-le, dar păstrează structura cât mai simplă, pe maximum două niveluri de dinamică. Dacă ai nevoie de structuri super complexe de permisiuni, mai bine mergi pe o validare runtime cu un tool precum Zod, combinat cu tipuri ceva mai relaxate.

Voi cum gestionați permisiunile în aplicațiile mari de TS? Mergeți pe string-uri chioare și validare la runtime, sau lăsați compilatorul să facă munca grea?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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