DEV Community

Safal Bhandari
Safal Bhandari

Posted on

Zod Inference

Zod is a TypeScript-first schema declaration and validation library. You define schemas that validate data at runtime, while also inferring TypeScript types automatically.

Example:

import { z } from "zod";

const UserSchema = z.object({
  id: z.string(),
  age: z.number().min(18),
  email: z.string().email(),
});
Enter fullscreen mode Exit fullscreen mode

Here UserSchema validates that an object has a string id, a number age ≥ 18, and a valid email.


Type Inference in Zod

The key feature: you do not need to manually define a matching TypeScript type. Instead, you extract it from the schema.

type User = z.infer<typeof UserSchema>;
Enter fullscreen mode Exit fullscreen mode

Now User is equivalent to:

type User = {
  id: string;
  age: number;
  email: string;
};
Enter fullscreen mode Exit fullscreen mode

This ensures runtime checks (Zod validation) and compile-time safety (TypeScript typing) are always consistent.


Why Use Zod Inference?

  1. Eliminates duplication: No need to manually sync types and validation.
  2. Ensures safety: If you change the schema, the type updates automatically.
  3. Improves maintainability: One source of truth for both runtime and type-level constraints.

Practical Example

const TodoSchema = z.object({
  title: z.string().min(3),
  completed: z.boolean(),
  dueDate: z.date().optional(),
});

// inferred type
type Todo = z.infer<typeof TodoSchema>;

const data: unknown = {
  title: "Learn Zod",
  completed: true,
};

const parsed = TodoSchema.parse(data); // ✅ runtime validation
Enter fullscreen mode Exit fullscreen mode
  • parsed has type Todo.
  • If data fails validation, Zod throws an error.
  • The TypeScript compiler knows parsed.title is a string, parsed.completed is a boolean, and parsed.dueDate may be Date | undefined.

Advanced Inference Cases

  • Union Types
const StatusSchema = z.union([z.literal("active"), z.literal("inactive")]);
type Status = z.infer<typeof StatusSchema>; // "active" | "inactive"
Enter fullscreen mode Exit fullscreen mode
  • Arrays
const Numbers = z.array(z.number());
type NumbersType = z.infer<typeof Numbers>; // number[]
Enter fullscreen mode Exit fullscreen mode
  • Nested Objects
const Profile = z.object({
  user: UserSchema,
  hobbies: z.array(z.string()),
});
type ProfileType = z.infer<typeof Profile>;
Enter fullscreen mode Exit fullscreen mode

Conclusion

Zod inference bridges runtime validation with static type safety. Instead of maintaining separate validation logic and TypeScript interfaces, you define schemas once and extract types automatically. This reduces bugs, prevents mismatches, and accelerates development.


Top comments (0)