Cea mai mare greșeală comisă în aplicațiile TypeScript este presupunerea că tipurile oferă siguranță asupra datelor primite din exterior. Din cauza mecanismului de Type Erasure, scrierea unui cod de forma:
const response = await fetch('/api/utilizator');
const user = await response.json() as User; // MINCIUNĂ PERICULOASĂ!
nu face nicio verificare reală la rulare! Dacă API-ul backend returnează o eroare 500 sub formă de HTML sau lipsește o proprietate critică, TypeScript nu va sesiza nimic, iar aplicația va crăpa câteva linii mai jos. Zod elimină această breșă prin combinarea validării de runtime cu inferența automată a tipurilor statice.
import { z } from 'zod';
// 1. Definim schema de validare la runtime:
export const UtilizatorSchema = z.object({
id: z.number().int().positive(),
nume: z.string().min(2, "Numele este prea scurt"),
email: z.string().email("Format email invalid"),
varsta: z.number().min(18).optional(),
rol: z.enum(['admin', 'editor', 'client']).default('client'),
created_at: z.coerce.date() // Transformă automat string-ul ISO în instanță Date!
});
// 2. MAGIA: Nu mai scriem o interfață manuală! O deducem direct din schemă:
export type Utilizator = z.infer<typeof UtilizatorSchema>;
// TypeScript generează automat tipul identic cu schema:
// { id: number; nume: string; email: string; varsta?: number | undefined; rol: "admin" | "editor" | "client"; created_at: Date; }
Parsare Sigură: safeParse vs parse
| Metodă | Comportament la Succes | Comportament la Eroare | Caz Recomandat |
|---|---|---|---|
schema.parse(date) |
Returnează datele validate și transformate. | Aruncă excepție ZodError. |
Middleware-uri unde erorile sunt prinse într-un errorHandler global. |
schema.safeParse(date) |
Returnează { success: true, data: T } |
Returnează { success: false, error: ZodError } (fără throw!) |
Validare formulare React/Vue, endpoints de API REST, webhook-uri. |
async function incarcaDateClient(jsonBrut: unknown) {
const rezultat = UtilizatorSchema.safeParse(jsonBrut);
if (!rezultat.success) {
// Obținem erorile structurate pe câmpuri pentru afișare în UI:
console.error("Validare eșuată:", rezultat.error.flatten().fieldErrors);
return null;
}
// rezultat.data este 100% sigur și tipat complet ca 'Utilizator':
console.log(`Utilizator validat: ${rezultat.data.nume}`);
return rezultat.data;
}
Conceptul de End-to-End Type Safety (tRPC)
Într-o arhitectură modernă tRPC sau Hono OpenAPI, schemele Zod din backend sunt exportate ca tipuri directe către frontend. Când un dezvoltator modifică tipul unei coloane sau adaugă un câmp obligatoriu în backend, proiectul de frontend nu mai compilează în editor până când apelul nu este actualizat corespunzător! Aceasta elimină definitiv erorile de desincronizare între frontend și backend.