Formularios con seguridad de tipos y contratos de respuestas de API
Utilice Zod para inferir tipos de TypeScript a partir de esquemas y validar tanto los datos de formularios como las respuestas de API.
Formularios con seguridad de tipos y contratos de respuestas de API es una lección gratuita de React Academy en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de React Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de React Academy incluye 4 lecciones en total.
Por qué son importantes las estructuras de datos seguras en cuanto a tipos
Los formularios y las respuestas de API son límites por los que entran datos no confiables en la aplicación. Zod permite definir esquemas que validan en tiempo de ejecución y, a la vez, infieren tipos de TypeScript.
Conceptos básicos de los esquemas de Zod
Defina esquemas con la API fluida de Zod. Use z.infer<typeof schema> para extraer el tipo de 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 con el resolver de Zod
Integre esquemas de Zod con React Hook Form para validar formularios de forma segura en cuanto a tipos; TypeScript conoce la estructura de los datos y los errores del formulario.
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
};
}Validación de respuestas de API
Analice las respuestas de la API con Zod para detectar desajustes de estructura en el límite; si la API devuelve datos inesperados, obtendrá un error detallado en lugar de un fallo en tiempo de ejecución en lo más profundo del 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álisis seguro para gestionar errores con elegancia
Use schema.safeParse() para obtener un objeto de resultado en lugar de lanzar una excepción; es ideal para la validación de formularios cuando desea mostrar errores al usuario.
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 typedUniones discriminadas con Zod
Utilice z.discriminatedUnion para modelar respuestas de API que tienen distintas estructuras según una marca de éxito o error.
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 }Transformaciones de Zod
Utilice .transform() para convertir o reestructurar datos durante el análisis; por ejemplo, para convertir una cadena de fecha en un 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 }Reutilización de esquemas
Derive los esquemas de creación y actualización a partir del esquema base para evitar duplicaciones.
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>;Server Action con Zod
Valide los datos de un formulario en una Server Action de Next.js con Zod antes de acceder a la base de datos.
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 compartidos entre frontend y backend
Exporte los esquemas de Zod desde un paquete compartido para que el frontend y el backend utilicen la misma lógica de validación: un único esquema como fuente de verdad.
// 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';Mensajes de error de Zod
Personalice los mensajes de error de cada campo para mejorar la experiencia de usuario; Zod los transfiere automáticamente a la vista de errores del formulario mediante el resolver.
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'),
});Comprobación rápida
¿Qué proporciona z.infer
Repaso
Defina los esquemas de Zod una sola vez y utilice z.infer para derivar tipos de TypeScript. Utilice zodResolver en React Hook Form para obtener una validación con seguridad de tipos. Analice las respuestas de API con Zod en el límite de entrada, utilice safeParse para mostrar errores al usuario y comparta los esquemas entre el frontend y el backend mediante un paquete compartido.
Preguntas frecuentes
¿La lección «Formularios con seguridad de tipos y contratos de respuestas de API» es gratis?
Sí — el texto completo de «Formularios con seguridad de tipos y contratos de respuestas de API» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de React Academy, actualiza a CoddyKit PRO. El curso de React Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Formularios con seguridad de tipos y contratos de respuestas de API»?
Utilice Zod para inferir tipos de TypeScript a partir de esquemas y validar tanto los datos de formularios como las respuestas de API. Practicas React Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar React Academy?
No se requiere experiencia previa. React Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Formularios con seguridad de tipos y contratos de respuestas de API»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de React Academy?
Sí. Cada lección de React Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Uniones discriminadas para variantes de componentes
- Tipos condicionales y mapeados en React
- Componentes polimórficos con la prop 'as'
- Formularios con seguridad de tipos y contratos de respuestas de API