React
Validazione con Zod
Zod valida un oggetto a runtime e ne ricava il tipo TypeScript: uno schema, errori per campo e un tipo che non può divergere dalla regola.
In sintesi
- Lo schema Zod è l’unica fonte della regola e del tipo.
- safeParse restituisce un risultato invece di lanciare.
- fieldErrors è già una mappa per campo, pronta per l’interfaccia.
- Lo stesso schema va rieseguito sul server.
Zod valida un oggetto a runtime e ne ricava il tipo TypeScript: dichiari lo schema una volta e ottieni errori per campo e un tipo che non può divergere dalla regola.
Lo schema è il contratto
Uno schema Zod descrive forma e regole di un oggetto, e z.infer estrae il tipo corrispondente: la regola e il tipo vengono dalla stessa riga, quindi non possono divergere dopo una modifica.
import { z } from "zod";
export const signupSchema = z.object({
email: z.email(),
password: z.string().min(12),
age: z.coerce.number().int().min(18),
});
export type SignupValues = z.infer;
Leggere gli errori per campo
const parsed = signupSchema.safeParse({ email: "nope", password: "short", age: "17" });
if (!parsed.success) {
const errors = parsed.error.flatten().fieldErrors;
// { email: ["Invalid email"], password: [...], age: [...] }
}
safeParse non lancia: restituisce un risultato con success e, in caso di errore, una mappa per campo. Quella mappa è già pronta per l’interfaccia, perché ogni chiave corrisponde a un input.
Lo stesso schema sul server
const body: unknown = await request.json();
const parsed = signupSchema.safeParse(body);
if (!parsed.success) {
return Response.json({ errors: parsed.error.flatten() }, { status: 400 });
}
La validazione nel browser è una comodità, non un controllo: una richiesta costruita a mano la salta. Lo stesso schema va rieseguito sul server, dove il dato entra davvero nel sistema.
Il comando
npm install zod
npx tsc --noEmit
Zod è distribuito con licenza MIT; il secondo comando controlla che il tipo dedotto dallo schema compili senza errori nel progetto.
Record vivi nel catalogo
Tre record mostrano la stessa idea di campo con errore associato: credit-card-form, login-form e la categoria blocchi form, dove ogni blocco ha già gli stati di errore.
La limitazione
Uno schema controlla la forma, non la verità: un indirizzo email sintatticamente valido può non esistere, e un’età di 18 anni non prova nulla. Unicità, permessi ed esistenza del dato restano al database.
Dove continuare
Chi possiede il valore di un campo è in form controllati e non; la validazione lato server è in Server Actions e validazione; l’integrazione con il form è in react-hook-form con Zod; il confronto fra le librerie è in librerie di form React.
Domande frequenti
Zod valida a runtime o solo in TypeScript?
A runtime. Il tipo è una conseguenza: lo schema esegue il controllo sui valori reali e ne deduce il tipo TypeScript.
safeParse o parse?
safeParse quando l’errore è atteso e va mostrato all’utente; parse quando un valore non valido è un bug e deve fermare l’esecuzione.
Posso usare lo stesso schema sul server?
Sì, ed è il punto: lo stesso oggetto schema gira in Node e nel browser, quindi la regola non viene duplicata.
Zod sostituisce la validazione HTML?
No. Gli attributi del browser danno un riscontro immediato senza JavaScript; Zod aggiunge regole che l’HTML non sa esprimere.
Perché zod pesa così tanto su npm?
Perché il pacchetto pubblicato contiene tutte le build, le lingue e i tipi. Al browser arriva solo la parte importata, dopo il tree shaking.