Introducción a Zod: Validar Datos con TypeScript

¡Bienvenido, aventurero del tipado! 🎩 TypeScript es genial, ¿verdad? Nos permite estructurar mejor nuestro código aportando tipado estático y nos ayuda a evitar bugs molestos. Pero aquí está el problema: TypeScript verifica los tipos... ¡solo en tiempo de compilación! 😬 Así es, una vez que tu código se está ejecutando, nada garantiza que los datos provenientes del exterior (API, usuarios, etc.) respetarán la estructura esperada. ¡Es aquí donde Zod entra en escena para salvarnos! 🚀

En este artículo, descubriremos por qué y cómo utilizar Zod, una biblioteca que te permite validar y tipar tus datos dinámicamente. Desde la validación básica hasta estructuras de datos más complejas, Zod te ofrece todo lo necesario para asegurar tus datos en TypeScript sin compromisos. ¡Vamos allá! 🎉

¿Qué es Zod? 🤔

Zod es una librería de validación de esquemas en TypeScript que verifica tus datos en tiempo real. Con Zod, puedes crear esquemas de validación para cualquier tipo de objeto. Imagina una API que te devuelve datos inciertos: Zod permite verificar al instante que los datos recibidos corresponden al tipo esperado.

Algunas características clave de Zod 💪

  • Simple y flexible: Su sintaxis es intuitiva y expresiva.
  • Validación y tipado combinados: No necesitas hacer malabares entre tipos y validaciones separadas, ¡Zod maneja todo!
  • Feedback instantáneo: Obtienes errores detallados en cuanto tus datos no coinciden con el esquema.
  • API robusta: Desde validación simple hasta transformaciones complejas, Zod ofrece una API completa.

Instalación de Zod 📦

Para empezar, solo necesitas instalar Zod vía npm o yarn:

bash
1npm install zod
2# o
3yarn add zod
4# o
5pnpm add zod
6# o
7bun add zod

Ahora que estás listo, ¡sumerjámonos en la creación de tu primer esquema Zod!

Creación de Esquemas Básicos con Zod 🎨

Un esquema Zod representa una estructura de datos esperada. Tomemos un ejemplo simple donde queremos validar un usuario con un nombre, una edad y una dirección de email.

Ejemplo: Validación básica

Así es cómo definir un esquema Zod para un usuario 👤:

typescript
1import { z } from 'zod';
2
3// Esquema de usuario
4const userSchema = z.object({
5 name: z.string(), // El nombre debe ser una cadena
6 age: z.number().int().min(18), // La edad debe ser un entero, mínimo 18
7 email: z.string().email(), // Debe ser un email válido
8});
9
10// Ejemplo de datos de entrada
11const userInput = {
12 name: 'Alice',
13 age: 25,
14 email: 'alice@example.com',
15};
16
17// Validación de datos
18try {
19 const validUser = userSchema.parse(userInput); // Parse devuelve los datos validados
20 console.log('Usuario válido:', validUser);
21} catch (e) {
22 console.error('Error de validación:', e.errors);
23}

Con este ejemplo, Zod verificará si userInput respeta el esquema definido por userSchema. Si todo está en orden, parse devuelve los datos validados. Si no, lanza un error con un mensaje detallado sobre lo que está mal. ¡Sin sorpresas en producción! 🎉

Tipos Condicionales y Unión: Gestión de Casos Múltiples 🔀

Zod también maneja esquemas complejos gracias a los tipos condicionales. Digamos que tienes un formulario donde el usuario puede ser un cliente o un administrador. Así es como definir este esquema con Zod.

Ejemplo: Esquema con unión

typescript
1// Esquema cliente
2const clientSchema = z.object({
3 role: z.literal('cliente'),
4 preferences: z.array(z.string()), // Array de preferencias
5});
6
7// Esquema administrador
8const adminSchema = z.object({
9 role: z.literal('admin'),
10 accessLevel: z.number().min(1).max(5), // Nivel de acceso de 1 a 5
11});
12
13// Unión de los dos esquemas
14const userSchema = z.union([clientSchema, adminSchema]);
15
16// Ejemplo de usuario
17const adminUser = {
18 role: 'admin',
19 accessLevel: 3,
20};
21
22// Validación
23try {
24 const validUser = userSchema.parse(adminUser);
25 console.log('Usuario válido:', validUser);
26} catch (e) {
27 console.error('Error de validación:', e.errors);
28}

En este ejemplo, Zod valida que adminUser es ya sea un cliente o un admin con las propiedades requeridas para cada rol. ¿Práctico, no? 👌

Las Transformaciones: Validar y Transformar al Mismo Tiempo 🔄

A veces, quieres validar un dato y transformarlo al mismo tiempo. Zod permite hacerlo fácilmente, como por ejemplo transformando una cadena de caracteres en número.

Ejemplo: Transformación de datos

typescript
1const priceSchema = z.string().transform((val) => parseFloat(val));
2
3// Ejemplo de entrada
4const priceInput = '49.99';
5
6// Validación y transformación
7const validPrice = priceSchema.parse(priceInput);
8console.log('Precio validado y transformado:', validPrice); // 49.99 (número)

Aquí, Zod acepta una cadena de caracteres ("49.99") y la transforma en un número válido.

Validaciones Personalizadas 🛠️

Zod también permite crear validaciones a medida con el método .refine(). Supongamos que quieres validar una contraseña con criterios específicos, como una longitud mínima y la presencia de caracteres especiales.

Ejemplo: Validación de contraseña

typescript
1const passwordSchema = z
2 .string()
3 .min(8, { message: 'La contraseña debe tener al menos 8 caracteres' })
4 .refine((val) => /[A-Z]/.test(val), {
5 message: 'La contraseña debe contener al menos una mayúscula',
6 })
7 .refine((val) => /[0-9]/.test(val), {
8 message: 'La contraseña debe contener al menos un número',
9 });
10
11// Ejemplo de entrada
12const passwordInput = 'Secure123';
13
14// Validación
15try {
16 const validPassword = passwordSchema.parse(passwordInput);
17 console.log('Contraseña válida:', validPassword);
18} catch (e) {
19 console.error('Error de validación:', e.errors);
20}

El método .refine() permite añadir una condición personalizada. Aquí, Zod verifica que la contraseña respeta los criterios definidos, y proporciona mensajes de error específicos si no es el caso.

¿Por Qué Elegir Zod? 🌟

Zod se ha convertido en un imprescindible para la validación en TypeScript, porque:

  • Combina perfectamente validación y tipado, sin añadir complejidad.
  • Ofrece una API clara e intuitiva, incluso para esquemas complejos.
  • Proporciona errores comprensibles y fáciles de depurar.
  • Se integra perfectamente en proyectos TypeScript.

En resumen

Zod aporta una capa adicional de seguridad y fiabilidad a TypeScript validando los datos recibidos de manera dinámica. Podrás dormir tranquilo sabiendo que tus datos están sanos y bien tipados. Entonces, ¿listo para probar Zod en tu próximo proyecto? 😎

Comparte este artículo


Sébastien Timoner

Sébastien TIMONER

Desarrollador Líder
Experto en Desarrollo a Medida
Aix-en-Provence, France

Experto en desarrollo web y gestión de equipos técnicos, me especializo en la creación y optimización de soluciones digitales de alto rendimiento. Gracias a un profundo dominio de tecnologías modernas como React.js, Node.js, TypeScript y Symfony, garantizo el éxito de proyectos SaaS complejos, desde el diseño hasta la implementación, para empresas de diversos sectores, dentro de offroadLabs.

En offroadLabs, ofrezco servicios de desarrollo a medida, combinando experiencia técnica y enfoque colaborativo. Ya sea para crear una solución SaaS innovadora, modernizar una aplicación existente o acompañar el desarrollo de habilidades de un equipo, me comprometo a proporcionar soluciones robustas y eficientes, adaptadas a las necesidades específicas de cada proyecto.

Estoy disponible para proyectos en la zona de Aix-en-Provence o en modalidad totalmente remota.