Introduzione: Il Problema della Validazione in TypeScript
TypeScript ci regala la sicurezza dei tipi a compile-time, ma una volta che i dati entrano nel nostro sistema—ad esempio da un’API, un form utente o un file—questa protezione svanisce. I tipi di TypeScript sono solo un’illusione a runtime. Ecco dove entra in gioco la validazione: il processo di verifica che i dati in ingresso rispettino la forma e i vincoli attesi. Farlo manualmente è noioso, soggetto a errori e duplica la logica già espressa nei nostri tipi. Zod risolve questo problema in modo elegante.
Cos’è Zod e Perché È Rivoluzionario
Zod è una libreria di validazione degli schemi TypeScript-first. In altre parole, definisci uno “schema” (un blueprint) che descrive la forma dei tuoi dati. Questo schema fa due cose magicamente:
- Valida i dati a runtime: Verifica che un oggetto, un stringa, un numero, ecc., rispettino le regole.
- Inferisce automaticamente i tipi TypeScript: Dallo schema, Zod genera il tipo TypeScript corrispondente. Non c’è più duplicazione tra tipi e validator.
La filosofia di Zod è: “Definisci una volta, usa due volte”.
Installazione e Primi Passi
L’installazione è semplice con npm o yarn:
npm install zod
Ecco un esempio basilare che mostra la potenza:
import { z } from "zod";
// 1. Definisci lo schema
const UserSchema = z.object({
id: z.number().int().positive(),
username: z.string().min(3).max(30),
email: z.string().email(),
age: z.number().int().optional(), // campo opzionale
});
// 2. Zod inferisce automaticamente il tipo!
type User = z.infer<typeof UserSchema>;
// type User = {
// id: number;
// username: string;
// email: string;
// age?: number | undefined;
// }
// 3. Usa lo schema per validare
try {
const validUser = UserSchema.parse({
id: 1,
username: "john_doe",
email: "john@example.com",
age: 25
}); // Success! Restituisce l'oggetto tipizzato
const invalidUser = UserSchema.parse({
id: -5, // ❌ number deve essere positivo
username: "jo", // ❌ troppo corto
email: "non-è-un'email" // ❌ formato email valido
});
} catch (error) {
if (error instanceof z.ZodError) {
console.log(error.errors); // Array dettagliato degli errori
}
}
Vantaggi Chiave di Zod
Perché scegliere Zod rispetto ad altre soluzioni?
- TypeScript-First: L’integrazione è perfetta. Non ci sono tipi “any” nascosti.
- Messaggi di Errore Fantastici:Gli errori sono strutturati, localizzabili e facili da presentare all’utente finale.
- Composizione Potente: Gli schemi sono componibili. Puoi riutilizzare parti di uno schema in un altro.
- Ricco di Tipi Primitivi e Trasformazioni: Supporta stringhe, numeri, booleani, date, enum, array, tuple, oggetti, union, discriminated unions, e molto altro. Include metodi come
.email(),.url(),.regex(),.datetime(). - Parsing e Trasformazione: Con
.transform()puoi modificare i dati dopo la validazione (es. convertire stringhe in numeri, trimmare spazi). - Zero Dipendenze: Leggero e autonomo.
Casi d’Uso Pratici
Validare Dati API
Assicurati che le risposte del backend rispettino il contratto atteso prima di usarle nel frontend.
Validare Input Utente (Form)
Usa lo stesso schema per validare sia sul client (React Hook Form, Formik) che sul server (Node.js/Express, Next.js API Routes), garantendo coerenza.
Parsing di Configurazioni
Per file di configurazione (es. package.json, .env) o dati da localStorage, Zod garantisce che siano nel formato corretto.
Esempio Avanzato: Schemi Complessi e Transform
const ProductSchema = z.object({
id: z.string().uuid(),
name: z.string(),
price: z.string().transform((str, ctx) => {
const num = parseFloat(str);
if (isNaN(num)) {
ctx.addIssue({ code: z.ZodIssueCode.custom, message: "Prezzo non valido" });
return z.NEVER;
}
return num; // Trasforma la stringa in numero
}),
tags: z.array(z.string()).default([]),
metadata: z.record(z.any()).optional(),
});
Integrazione con Framework Moderni
Zod si integra splendidamente con:
- Next.js: Validare i params delle pagine (SSG/SSR), i body delle API routes.
- React: Con librarie come
react-hook-form(usandozodResolver) per una gestione form senza stress. - tRPC: tRPC usa Zod internamente per la validazione degli input/output. La combinazione è naturale.
- Express.js / Fastify: Middleware per validare
req.body,req.query, ecc.
Conclusione: Un Investimento Che Paga
Zod non è solo una libreria di validazione; è uno strumento che migliora drasticamente l’affidabilità, la manutenibilità e l’esperienza di sviluppo in un progetto TypeScript. Riduce il boilerplate, elimina la duplicazione e fornisce errori chiari. Se stai costruendo applicazioni dove i dati provengono dall’esterno (praticamente tutte), Zod è una scelta obbligata per dormire sonni tranquilli.