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

Cum m-am salvat de bug-uri de permisiuni folosind Template Literal Types

De Mihai Popescu, 29 apr. 2026 · 3 vizualizări · 3 like-uri

Postat acum 2 zile
typescript
type Resource = 'user' | 'post' | 'comment';
type Action = 'create' | 'read' | 'update' | 'delete';

type Permission = `api:${Resource}:${Action}`;

// Funcționează perfect:
const userRead: Permission = 'api:user:read';

// Eroare de compilare: Type 'api:user:write' is not assignable to type Permission
// const userWrite: Permission = 'api:user:write'; 

function checkPermission(p: Permission) {
  console.log(`Checking access for: ${p}`);
}

checkPermission('api:post:delete');

M-am tot lovit de sisteme de permisiuni unde totul era un string aruncat într-un if banal. La un proiect de acum doi ani, cu vreo 15 resurse diferite și 4 acțiuni de bază, am ajuns să avem bug-uri de producție doar pentru că cineva a scris user:write în loc de users:write. Pare o prostie, dar când ai 80 de rute și o echipă de 5 oameni care se grăbesc, typo-urile devin inevitabile.

Soluția clasică era să facem un enum imens sau un obiect cu constante, dar e un chin să le întreții. Aici intervin Template Literal Types, o funcționalitate care a schimbat radical modul în care scriu cod în ultimul timp. Practic, forțezi compilatorul să înțeleagă structura internă a unui string, nu doar să-l vadă ca pe o secvență de caractere.

De la string-uri loose la rigoare

Ideea e simplă: definești seturile de date atomice și apoi lași TypeScript să facă munca grea de combinatorică. Am pățit de multe ori să am nevoie de permisiuni de tipul api:user:read sau api:admin:delete. În loc să scriu manual fiecare combinație, definesc tipurile de bază pentru resurse și acțiuni.

Când combini aceste tipuri folosind sintaxa de backticks în interiorul unui type, TypeScript generează automat toate permutările posibile. E un sentiment super satisfăcător să vezi cum IDE-ul îți dă autocomplete exact pe string-ul compus, iar dacă încerci să trimiți ceva ce nu există în definiție, primești eroare imediat. La un proiect recent, am economisit cam 30% din timpul de debugging pe zona de autorizare doar pentru că am eliminat clasa asta de erori umane.

Unde se rupe filmul și care sunt limitările

Merge bine pentru structuri clare, dar e nasol dacă ai prea multe combinații. TypeScript are o limită de recursivitate și de număr de variante pe care le poate genera într-o uniune (undeva pe la 100.000, dar performanța scade mult mai devreme). Am încercat o dată să generez permisiuni granulare pentru un sistem complex de ERP și VS Code a început să înghețe la fiecare autocomplete.

Un alt trade-off sincer: codul devine un pic mai greu de citit pentru juniori sau pentru cineva care vine din ecosisteme mai puțin stricte, cum e PHP-ul vechi sau Python. Trebuie să explici echipei de ce nu pot să dea pur și simplu un string de la tastatură și de ce au nevoie de as const uneori. Nu e magic, e doar matematică de seturi aplicată pe string-uri.

Practic, cum te ajută la runtime?

Deși tipurile dispar la compilare, poți folosi Template Literal Types împreună cu Type Guards ca să te asiguri că datele care vin din baza de date sau dintr-un JWT sunt valide. Eu obișnuiesc să fac o funcție de validare care verifică formatul string-ului și face cast la tipul meu specific. Astfel, restul aplicației lucrează cu certitudini, nu cu presupuneri.

În final, întrebarea e: merită overhead-ul de a scrie aceste tipuri complexe? Pentru orice proiect care trece de 3-4 luni de dezvoltare și are mai mult de doi developeri, răspunsul meu e un „da” categoric. E mult mai ieftin să repari o eroare de tip în timpul scrierii codului decât să cauți de ce un admin nu poate șterge un comentariu duminică seara.

Voi cum gestionați string-urile astea structurate în proiectele mari? Mergeți pe Enums sau lăsați TypeScript să le genereze dinamic?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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