Formulários seguros quanto aos tipos e contratos de respostas de API
Use Zod para inferir tipos TypeScript a partir de esquemas e validar tanto dados de formulários quanto respostas de APIs.
Formulários seguros quanto aos tipos e contratos de respostas de API é uma aula grátis de React Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de React Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de React Academy inclui 4 aulas no total.
Por que formatos de dados seguros quanto aos tipos são importantes
Formulários e respostas de API são pontos de fronteira nos quais os dados entram na sua aplicação a partir de fontes não confiáveis. O Zod permite definir esquemas que validam em tempo de execução e também inferem tipos do TypeScript.
Noções básicas de esquemas do Zod
Defina esquemas com a API fluente do Zod. Use z.infer<typeof schema> para extrair o tipo do TypeScript.
import { z } from 'zod';
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(0).max(150).optional(),
role: z.enum(['admin', 'user', 'guest']),
});
type User = z.infer<typeof UserSchema>;
// { id: string; name: string; email: string; age?: number; role: 'admin'|'user'|'guest' }React Hook Form com o resolvedor do Zod
Integre esquemas do Zod ao React Hook Form para obter validação de formulários segura quanto aos tipos — o TypeScript conhece o formato dos dados e dos erros do formulário.
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
const LoginSchema = z.object({
email: z.string().email('Invalid email'),
password: z.string().min(8, 'At least 8 characters'),
});
type LoginData = z.infer<typeof LoginSchema>;
function LoginForm() {
const { register, handleSubmit, formState: { errors } } = useForm<LoginData>({
resolver: zodResolver(LoginSchema),
});
const onSubmit = (data: LoginData) => {
// data is LoginData — fully typed, already validated
};
}Validando respostas de API
Analise as respostas da API com o Zod para detectar incompatibilidades de formato na fronteira — se a API retornar dados inesperados, você obterá um erro detalhado em vez de uma falha em tempo de execução no interior do seu componente.
async function fetchUser(id: string): Promise<User> {
const res = await fetch(`/api/users/${id}`);
const json = await res.json();
return UserSchema.parse(json); // throws ZodError if shape is wrong
}Análise segura para erros controlados
Use schema.safeParse() para obter um objeto de resultado em vez de lançar uma exceção — ideal para validação de formulários quando você deseja mostrar os erros ao usuário.
const result = UserSchema.safeParse(formData);
if (!result.success) {
const errors = result.error.flatten().fieldErrors;
// { name: ['Must be at least 1 character'], email: ['Invalid email'] }
return errors;
}
const user = result.data; // User — fully typedUniões discriminadas com Zod
Utilize z.discriminatedUnion para modelar respostas de API com formatos diferentes, definidos por um indicador de sucesso ou erro.
const ApiResponse = z.discriminatedUnion('ok', [
z.object({ ok: z.literal(true), data: UserSchema }),
z.object({ ok: z.literal(false), error: z.string(), code: z.number() }),
]);
type ApiResult = z.infer<typeof ApiResponse>;
// { ok: true; data: User } | { ok: false; error: string; code: number }Transformações com Zod
Utilize .transform() para converter ou remodelar dados durante a análise — por exemplo, converter uma cadeia de caracteres de data em um objeto Date.
const DateSchema = z.string().transform(s => new Date(s));
// Input: '2024-01-15' → Output: Date object
const EventSchema = z.object({
title: z.string(),
date: z.string().pipe(z.coerce.date()),
});
type Event = z.infer<typeof EventSchema>;
// { title: string; date: Date }Reutilização de esquemas
Derive os esquemas de criação e atualização a partir do esquema base para evitar duplicação.
const UserSchema = z.object({ name: z.string(), email: z.string().email() });
// For creation: add password
const CreateUserSchema = UserSchema.extend({ password: z.string().min(8) });
// For update: all fields optional
const UpdateUserSchema = UserSchema.partial();
type CreateUser = z.infer<typeof CreateUserSchema>;
type UpdateUser = z.infer<typeof UpdateUserSchema>;Ação do servidor com Zod
Valide os dados do formulário em uma ação do servidor do Next.js com Zod antes de acessar o banco de dados.
async function createPost(formData: FormData) {
'use server';
const schema = z.object({ title: z.string().min(3), body: z.string().min(10) });
const result = schema.safeParse(Object.fromEntries(formData));
if (!result.success) return { errors: result.error.flatten().fieldErrors };
await db.post.create({ data: result.data });
revalidatePath('/blog');
redirect('/blog');
}Esquemas compartilhados entre frontend e backend
Exporte os esquemas do Zod de um pacote compartilhado para que o frontend e o backend utilizem a mesma lógica de validação — um único esquema como fonte de verdade.
// packages/schemas/src/user.ts
export const CreateUserSchema = z.object({ ... });
export type CreateUser = z.infer<typeof CreateUserSchema>;
// Frontend imports:
import { CreateUserSchema, CreateUser } from '@company/schemas';
// Backend imports:
import { CreateUserSchema } from '@company/schemas';Mensagens de erro do Zod
Personalize as mensagens de erro de cada campo para melhorar a experiência do usuário — o Zod as envia automaticamente para a exibição de erros do formulário por meio do resolvedor.
const RegistrationSchema = z.object({
username: z.string()
.min(3, 'Username must be at least 3 characters')
.max(20, 'Username cannot exceed 20 characters')
.regex(/^[a-z0-9_]+$/, 'Only lowercase letters, numbers, and underscores'),
});Verificação rápida
O que z.infer<typeof MySchema> fornece no TypeScript?
Recapitulação
Defina os esquemas do Zod uma vez e utilize z.infer para derivar tipos do TypeScript. Utilize zodResolver no React Hook Form para obter uma validação segura em relação aos tipos. Analise as respostas da API com o Zod na fronteira do sistema, utilize safeParse para erros exibidos ao usuário e compartilhe os esquemas entre o frontend e o backend por meio de um pacote compartilhado.
Perguntas Frequentes
A aula “Formulários seguros quanto aos tipos e contratos de respostas de API” é grátis?
Sim — o texto completo de “Formulários seguros quanto aos tipos e contratos de respostas de API” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de React Academy, atualize para CoddyKit PRO. O curso de React Academy inclui 4 aulas no total.
O que vou aprender em “Formulários seguros quanto aos tipos e contratos de respostas de API”?
Use Zod para inferir tipos TypeScript a partir de esquemas e validar tanto dados de formulários quanto respostas de APIs. Você pratica React Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar React Academy?
Nenhuma experiência prévia é necessária. React Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Formulários seguros quanto aos tipos e contratos de respostas de API”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de React Academy?
Sim. Cada aula de React Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Uniões discriminadas para variantes de componentes
- Tipos condicionais e mapeados no React
- Componentes polimórficos com a propriedade 'as'
- Formulários seguros quanto aos tipos e contratos de respostas de API