Schema validation with zod & inference to TS
Validate requests with zod; infer TypeScript types from schemas; add safe middleware and error handling.
Schema validation with zod & inference to TS is a free TypeScript Academy lesson on CoddyKit — lesson 2 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Intro
Goal: Validate inbound data with zod and keep TypeScript types in sync via z.infer. You will parse safely, send helpful errors, and plug validation into middleware.
- Define schemas once
- Infer TS types
- safeParse + 400 errors
Schema + infer
Model once with zod. The derived type User = z.infer<typeof userSchema> mirrors validation exactly.
import { z } from "zod"
export const userSchema = z.object({
id: z.string().regex(/^u_[a-z0-9]+$/),
name: z.string().min(1),
age: z.number().int().nonnegative().optional()
})
export type User = z.infer<typeof userSchema>
// Reuse `User` across handlers, services, and testssafeParse in handler
Use safeParse to avoid exceptions; return 400 with formatted issues. The response type reflects both success and error shapes.
import { Request, Response } from "express"
import { userSchema, User } from "./schema"
export function createUser(req: Request<{}, User, unknown>, res: Response<User | { error: string; issues?: unknown }>) {
const parsed = userSchema.safeParse(req.body)
if (!parsed.success) {
return res.status(400).json({ error: "Invalid body", issues: parsed.error.format() })
}
const user = parsed.data
return res.status(201).json(user)
}Middleware helper
Create a reusable middleware. It parses the body and either attaches the typed data or returns a 400 with details.
import { z } from "zod"
import { Request, Response, NextFunction } from "express"
export function validateBody<T extends z.ZodTypeAny>(schema: T) {
return (req: Request, res: Response, next: NextFunction) => {
const r = schema.safeParse(req.body)
if (!r.success) {
return res.status(400).json({ error: "Invalid body", issues: r.error.format() })
}
req.body = r.data
next()
}
}Coercion & refine
Use z.coerce to accept string numbers, z.enum for known values, and .refine for cross-field rules.
import { z } from "zod"
const signupSchema = z.object({
email: z.string().email(),
age: z.coerce.number().int().gte(13),
role: z.enum(["user", "admin"]).default("user")
}).refine(v => v.role !== "admin" || v.age >= 18, { message: "admin must be adult" })
export type Signup = z.infer<typeof signupSchema>
// Coercion allows numbers in strings; refine adds cross-field rulesError tips
Error tips:
- Always use
safeParseat the edge. - Format issues for clients; avoid leaking stack traces.
- Narrow
unknowntoZodErrorif you catch thrown parses.
zod inference check
Quick check: How do you keep TS types in sync with zod schemas?
Recap
Recap: Define one schema, infer the TS type, validate with safeParse, and plug it into middleware for consistent 400 errors.
Frequently asked questions
Is the “Schema validation with zod & inference to TS” lesson free?
Yes — the full text of “Schema validation with zod & inference to TS” is free to read here on the web, and the TypeScript Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Schema validation with zod & inference to TS”?
Validate requests with zod; infer TypeScript types from schemas; add safe middleware and error handling. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 3, so you can start here or from the beginning and move at your own pace.
How long does the “Schema validation with zod & inference to TS” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Router handlers, Request/Response typing
- Schema validation with zod & inference to TS
- Error middleware & result types