Como converter JSON para Zod e validar dados da API
Gere schemas Zod a partir de um JSON, valide respostas de API em tempo de execução e refine o schema com e-mail, opcionais e valores nulos.
Publicado em
Tipos não validam nada em tempo de execução
As interfaces do TypeScript desaparecem quando o código é compilado. Se uma API passa a devolver um campo com outro formato, ou deixa de enviar um campo, a sua aplicação só descobre quando quebra. O Zod resolve isso: você descreve o formato esperado em um schema e ele confere os dados de verdade, na hora em que chegam.
Escrever schemas à mão para respostas grandes dá trabalho. Converter um JSON de exemplo em um schema Zod entrega a estrutura pronta para você refinar.
Passo a passo
- Abra o Transform e escolha JSON → Zod.
- Cole um JSON representativo da resposta que você quer validar.
- Ajuste o Nome raiz (aqui,
Usuario) e clique em Transformar. - Instale a biblioteca com
npm install zod, importeze cole os schemas gerados.
Exemplo
Entrada e resultado reais da ferramenta:
{
"id": 1,
"nome": "Ana Souza",
"email": "ana@exemplo.com",
"ativo": true,
"tags": ["admin", "beta"],
"endereco": { "cidade": "São Paulo", "cep": "01310-100" }
}const enderecoSchema = z.object({
cidade: z.string(),
cep: z.string(),
});
const usuarioSchema = z.object({
id: z.number(),
nome: z.string(),
email: z.string(),
ativo: z.boolean(),
tags: z.array(z.string()),
endereco: enderecoSchema,
});Objetos aninhados viram schemas separados (enderecoSchema) que o schema principal reutiliza, o que deixa o código organizado e fácil de reaproveitar.
Validando a resposta da API
import { z } from "zod";
// ... schemas gerados pela ferramenta ...
// O tipo TypeScript sai do próprio schema, sem escrever a interface à mão.
type Usuario = z.infer<typeof usuarioSchema>;
const resposta = await fetch("/api/usuarios/1");
const resultado = usuarioSchema.safeParse(await resposta.json());
if (!resultado.success) {
console.error("Resposta fora do formato esperado:", resultado.error.issues);
} else {
console.log(resultado.data.nome); // aqui os dados já foram validados
}Prefira safeParse quando quiser tratar o erro sem lançar exceção: ele devolve um objeto com success e, em caso de falha, a lista de problemas encontrados e em qual campo.
Refinando o schema
A ferramenta infere os tipos básicos a partir do exemplo: textos viram z.string(), números viram z.number() e assim por diante. Regras mais específicas são com você:
const usuarioSchema = z.object({
id: z.number().int().positive(),
nome: z.string().min(1),
email: z.string().email(),
ativo: z.boolean(),
tags: z.array(z.string()),
apelido: z.string().optional(), // pode não vir na resposta
ultimoLogin: z.string().nullable(), // pode vir como null
});Campos que só aparecem às vezes
Um exemplo não mostra quais campos são opcionais. Compare com a documentação da API e use.optional() e .nullable() onde fizer sentido.Já tem as interfaces? Converta direto do TypeScript
Se você já escreveu os tipos, use a conversão TypeScript → Zod: cole a interface e receba o schema equivalente, sem passar por um JSON de exemplo. Diferente da inferência a partir de JSON, aqui a ferramenta enxerga o que os tipos dizem, então preserva campos opcionais, valores nulos e uniões de valores literais:
type Papel = "admin" | "user";
interface Usuario {
id: number;
nome: string;
email?: string;
papel: Papel;
apelido: string | null;
}const usuarioSchema = z.object({
id: z.number(),
nome: z.string(),
email: z.string().optional(),
papel: z.enum(["admin", "user"]),
apelido: z.string().nullable(),
});email?: stringvirou.optional()."admin" | "user"virouz.enum([...]), mesmo passando pelo apelidoPapel.string | nullvirou.nullable().
Tipos mais avançados (genéricos, Partial, Record, tuplas, intersecções com & e o tipo Date) ainda saem simplificados como z.unknown(); revise o resultado nesses casos.
Quando usar só tipos e quando usar Zod
- Só tipos: para dados que nascem dentro da sua própria aplicação e que você controla.
- Zod: em toda fronteira com o mundo externo, como respostas de API, formulários, arquivos enviados, variáveis de ambiente e conteúdo do localStorage.
Perguntas frequentes
Preciso instalar o Zod?
Sim. O código gerado usa a biblioteca Zod, que se instala com npm install zod. A ferramenta gera apenas os schemas; o import de z fica por sua conta.
O Zod substitui as interfaces do TypeScript?
Na prática, sim. Com z.infer você obtém o tipo TypeScript a partir do schema, então mantém uma única definição em vez de duas.
Qual a diferença entre Zod e JSON Schema?
Zod é uma biblioteca de validação para TypeScript. JSON Schema é um padrão independente de linguagem, útil para documentação e para trocar contratos com outros sistemas. O Transform também converte JSON em JSON Schema.
O schema gerado já é o definitivo?
É um ponto de partida. Ele descreve o formato do exemplo que você colou, com tipos básicos. Regras como formato de e-mail, valores mínimos, campos opcionais e nulos você acrescenta depois.