DEV Community

Alex Spinov
Alex Spinov

Posted on

Zod Has a Free API: TypeScript-First Schema Validation That Actually Works

Why Zod

Zod validates data AND gives you TypeScript types from schemas. Define once, validate at runtime, get types at compile time. No more duplicating types and validation logic.

Install

npm install zod
Enter fullscreen mode Exit fullscreen mode

Basic Schemas

import { z } from 'zod';

const UserSchema = z.object({
  name: z.string().min(2),
  email: z.string().email(),
  age: z.number().int().min(18).max(120),
  role: z.enum(['admin', 'user', 'moderator']),
  bio: z.string().optional(),
});

type User = z.infer<typeof UserSchema>;
// { name: string; email: string; age: number; role: 'admin'|'user'|'moderator'; bio?: string }

const user = UserSchema.parse({
  name: 'Alice',
  email: 'alice@example.com',
  age: 30,
  role: 'admin',
});
Enter fullscreen mode Exit fullscreen mode

API Validation

import express from 'express';
import { z } from 'zod';

const CreateOrderSchema = z.object({
  productId: z.string().uuid(),
  quantity: z.number().int().positive(),
  coupon: z.string().optional(),
});

app.post('/orders', (req, res) => {
  const result = CreateOrderSchema.safeParse(req.body);
  if (!result.success) {
    return res.status(400).json({ errors: result.error.flatten() });
  }
  const order = result.data; // Fully typed!
  // ...
});
Enter fullscreen mode Exit fullscreen mode

Transform and Refine

const DateSchema = z.string().transform((s) => new Date(s));

const PasswordSchema = z.string()
  .min(8)
  .refine((pw) => /[A-Z]/.test(pw), 'Must contain uppercase')
  .refine((pw) => /[0-9]/.test(pw), 'Must contain number');

const PaginationSchema = z.object({
  page: z.coerce.number().int().positive().default(1),
  limit: z.coerce.number().int().min(1).max(100).default(20),
});
Enter fullscreen mode Exit fullscreen mode

Key Features

  • Type inference — z.infer gives TypeScript types from schemas
  • Runtime validation — parse() and safeParse()
  • Composable — .extend(), .merge(), .pick(), .omit()
  • Transforms — coerce, transform, preprocess
  • Error formatting — flatten(), format()
  • Zero dependencies — tiny bundle

Resources


Need to extract API schemas, validation patterns, or TypeScript type data? Check out my Apify tools or email spinov001@gmail.com for custom solutions.

Top comments (0)