šŸ“„ zod/basics

File: basics.md | Updated: 11/16/2025

Source: https://zod.dev/basics?id=inferring-types

šŸ’Ž Zod 4 is now stable! Ā Read the announcement.

Basic usage

Copy markdown

Edit this page

This page will walk you through the basics of creating schemas, parsing data, and using inferred types. For complete documentation on Zod's schema API, refer to Defining schemas .

Defining a schema


Before you can do anything else, you need to define a schema. For the purposes of this guide, we'll use a simple object schema.

ZodZod Mini

import * as z from "zod"; 
 
const Player = z.object({ 
  username: z.string(),
  xp: z.number()
});

Parsing data


Given any Zod schema, use .parse to validate an input. If it's valid, Zod returns a strongly-typed deep clone of the input.

Player.parse({ username: "billie", xp: 100 }); 
// => returns { username: "billie", xp: 100 }

Note — If your schema uses certain asynchronous APIs like async refinements or transforms , you'll need to use the .parseAsync() method instead.

await Player.parseAsync({ username: "billie", xp: 100 }); 

Handling errors


When validation fails, the .parse() method will throw a ZodError instance with granular information about the validation issues.

ZodZod Mini

try {
  Player.parse({ username: 42, xp: "100" });
} catch(error){
  if(error instanceof z.ZodError){
    error.issues; 
    /* [\
      {\
        expected: 'string',\
        code: 'invalid_type',\
        path: [ 'username' ],\
        message: 'Invalid input: expected string'\
      },\
      {\
        expected: 'number',\
        code: 'invalid_type',\
        path: [ 'xp' ],\
        message: 'Invalid input: expected number'\
      }\
    ] */
  }
}

To avoid a try/catch block, you can use the .safeParse() method to get back a plain result object containing either the successfully parsed data or a ZodError. The result type is a discriminated union , so you can handle both cases conveniently.

const result = Player.safeParse({ username: 42, xp: "100" });
if (!result.success) {
  result.error;   // ZodError instance
} else {
  result.data;    // { username: string; xp: number }
}

Note — If your schema uses certain asynchronous APIs like async refinements or transforms , you'll need to use the .safeParseAsync() method instead.

await schema.safeParseAsync("hello");

Inferring types


Zod infers a static type from your schema definitions. You can extract this type with the z.infer<> utility and use it however you like.

const Player = z.object({ 
  username: z.string(),
  xp: z.number()
});
 
// extract the inferred type
type Player = z.infer<typeof Player>;
 
// use it in your code
const player: Player = { username: "billie", xp: 100 };

In some cases, the input & output types of a schema can diverge. For instance, the .transform() API can convert the input from one type to another. In these cases, you can extract the input and output types independently:

const mySchema = z.string().transform((val) => val.length);
 
type MySchemaIn = z.input<typeof mySchema>;
// => string
 
type MySchemaOut = z.output<typeof mySchema>; // equivalent to z.infer<typeof mySchema>
// number

Now that we have the basics covered, let's jump into the Schema API.

Intro

Introduction to Zod - TypeScript-first schema validation library with static type inference
Defining schemas

Complete API reference for all Zod schema types, methods, and validation features

On this page

Defining a schema Parsing data Handling errors Inferring types