One zod schema is the single source of truth — it types the form and validates it. Type
invalid values and watch field-level errors and form state update live.
Form state
// the schema types AND validatesconst schema = z.object({
username: z.string().min(3).max(20).regex(/^\w+$/),
email: z.string().email(),
age: z.coerce.number().int().min(13),
password: z.string().min(8).regex(/\d/),
});
type FormValues = z.infer<typeof schema>;