Introdução à Validação com Zod

Iniciante | 40 min leitura | 2025.12.04

O que você vai aprender neste tutorial

✓ Fundamentos do Zod
✓ Definição de schemas
✓ Validação
✓ Inferência de tipos
✓ Integração com React Hook Form

Step 1: Configuração

npm install zod

Step 2: Schema Básico

import { z } from 'zod';

// Tipos primitivos
const stringSchema = z.string();
const numberSchema = z.number();
const booleanSchema = z.boolean();

// Objeto
const userSchema = z.object({
  name: z.string().min(1, 'Nome é obrigatório'),
  email: z.string().email('Digite um endereço de e-mail válido'),
  age: z.number().int().positive().optional(),
});

// Inferir tipo
type User = z.infer<typeof userSchema>;

Step 3: Validação

// parse - lança exceção em caso de falha
try {
  const user = userSchema.parse({
    name: 'Alice',
    email: 'alice@example.com'
  });
} catch (error) {
  if (error instanceof z.ZodError) {
    console.log(error.errors);
  }
}

// safeParse - retorna objeto mesmo em caso de falha
const result = userSchema.safeParse(data);
if (result.success) {
  console.log(result.data);
} else {
  console.log(result.error.flatten());
}

Step 4: Schemas Avançados

// Array
const tagsSchema = z.array(z.string()).min(1).max(5);

// Union
const statusSchema = z.enum(['active', 'inactive', 'pending']);

// Transformação
const numberStringSchema = z.string().transform(val => parseInt(val, 10));

// Refinamento
const passwordSchema = z.string()
  .min(8, 'Mínimo de 8 caracteres')
  .refine(val => /[A-Z]/.test(val), 'Inclua uma letra maiúscula')
  .refine(val => /[0-9]/.test(val), 'Inclua um número');

// Validação condicional
const formSchema = z.object({
  password: z.string(),
  confirmPassword: z.string()
}).refine(data => data.password === data.confirmPassword, {
  message: 'As senhas não coincidem',
  path: ['confirmPassword']
});

Step 5: Integração com React Hook Form

npm install react-hook-form @hookform/resolvers
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

const schema = z.object({
  name: z.string().min(1, 'Nome é obrigatório'),
  email: z.string().email('Digite um endereço de e-mail válido'),
});

type FormData = z.infer<typeof schema>;

function ContactForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
    resolver: zodResolver(schema)
  });

  const onSubmit = (data: FormData) => {
    console.log(data);
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('name')} />
      {errors.name && <span>{errors.name.message}</span>}

      <input {...register('email')} />
      {errors.email && <span>{errors.email.message}</span>}

      <button type="submit">Enviar</button>
    </form>
  );
}

Step 6: Validação de API

// Next.js API Route
import { z } from 'zod';

const createUserSchema = z.object({
  name: z.string(),
  email: z.string().email(),
});

export async function POST(request: Request) {
  const body = await request.json();
  const result = createUserSchema.safeParse(body);

  if (!result.success) {
    return Response.json(
      { errors: result.error.flatten() },
      { status: 400 }
    );
  }

  // result.data é type-safe
  const user = await createUser(result.data);
  return Response.json(user, { status: 201 });
}

Resumo

Zod integra inferência de tipos e validação, permitindo validação de entrada type-safe em projetos TypeScript.

← Voltar para a lista