zod
Version:
TypeScript-first schema declaration and validation library with static type inference
1,358 lines (1,107 loc) • 101 kB
Markdown
<p align="center">
<img src="https://raw.githubusercontent.com/colinhacks/zod/main/logo.svg" width="200px" align="center" alt="Zod logo" />
<h1 align="center">Zod</h1>
<p align="center">
<a href="https://zod.dev">zod.dev</a>
<br/>
TypeScript-first schema validation with static type inference
</p>
</p>
<p align="center">
<a href="https://github.com/colinhacks/zod/actions?query=branch%3Amain"><img src="https://github.com/colinhacks/zod/actions/workflows/test.yml/badge.svg?event=push&branch=main" alt="Zod CI status" /></a>
<a href="https://twitter.com/colinhacks" rel="nofollow"><img src="https://img.shields.io/badge/created%20by-@colinhacks-4BBAAB.svg" alt="Created by Colin McDonnell"></a>
<a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://img.shields.io/github/license/colinhacks/zod" alt="License"></a>
<a href="https://www.npmjs.com/package/zod" rel="nofollow"><img src="https://img.shields.io/npm/dw/zod.svg" alt="npm"></a>
<a href="https://github.com/colinhacks/zod" rel="nofollow"><img src="https://img.shields.io/github/stars/colinhacks/zod" alt="stars"></a>
</p>
<div align="center">
<a href="https://zod.dev">Website</a>
<span> • </span>
<a href="https://discord.gg/RcG33DQJdf">Discord</a>
<span> • </span>
<a href="https://twitter.com/colinhacks">𝕏</a>
<span> • </span>
<a href="https://bsky.app/profile/zod.dev">Bluesky</a>
<br />
</div>
<br/><br/>
<table align="center" style="justify-content:center;align-items:center;display:flex;"><td>
<p align="center">Zod 4 is now in beta!
<br/>
<a target="_blank" rel="noopener noreferrer" href="https://v4.zod.dev/v4">Read the announcement 👉</a></p></td>
</table>
<br/>
<br/>
<h2 align="center">Featured sponsor: Stainless</h2>
<div align="center">
<a href="https://www.stainless.com/?utm_source=zod">
<picture width="95%" >
<source media="(prefers-color-scheme: dark)" srcset="https://i.imgur.com/bjyoaHY.jpeg">
<img alt="stainless logo" src="https://i.imgur.com/bjyoaHY.jpeg" width="95%">
</picture>
</a>
<br/>
<p><sub>Learn more about <a target="_blank" rel="noopener noreferrer" href="mailto:sponsorship@colinhacks.com">featured sponsorships</a></sub></p>
</div>
<!-- <hr/> -->
<br/>
<br/>
## Table of contents
> These docs have been translated into [Chinese](./README_ZH.md) and [Korean](./README_KO.md).
- [Table of contents](#table-of-contents)
- [Introduction](#introduction)
- [Sponsors](#sponsors)
- [Platinum](#platinum)
- [Gold](#gold)
- [Silver](#silver)
- [Bronze](#bronze)
- [Copper](#copper)
- [Ecosystem](#ecosystem)
- [Resources](#resources)
- [API libraries](#api-libraries)
- [Form integrations](#form-integrations)
- [Zod to X](#zod-to-x)
- [X to Zod](#x-to-zod)
- [Mocking](#mocking)
- [Powered by Zod](#powered-by-zod)
- [Utilities for Zod](#utilities-for-zod)
- [Installation](#installation)
- [Requirements](#requirements)
- [From `npm`](#from-npm)
- [Basic usage](#basic-usage)
- [Primitives](#primitives)
- [Coercion for primitives](#coercion-for-primitives)
- [Literals](#literals)
- [Strings](#strings)
- [Datetimes](#datetimes)
- [Dates](#dates)
- [Times](#times)
- [IP addresses](#ip-addresses)
- [IP ranges](#ip-ranges-cidr)
- [Numbers](#numbers)
- [BigInts](#bigints)
- [NaNs](#nans)
- [Booleans](#booleans)
- [Dates](#dates-1)
- [Zod enums](#zod-enums)
- [Native enums](#native-enums)
- [Optionals](#optionals)
- [Nullables](#nullables)
- [Objects](#objects)
- [`.shape`](#shape)
- [`.keyof`](#keyof)
- [`.extend`](#extend)
- [`.merge`](#merge)
- [`.pick/.omit`](#pickomit)
- [`.partial`](#partial)
- [`.deepPartial`](#deeppartial)
- [`.required`](#required)
- [`.passthrough`](#passthrough)
- [`.strict`](#strict)
- [`.strip`](#strip)
- [`.catchall`](#catchall)
- [Arrays](#arrays)
- [`.element`](#element)
- [`.nonempty`](#nonempty)
- [`.min/.max/.length`](#minmaxlength)
- [Tuples](#tuples)
- [Unions](#unions)
- [Discriminated unions](#discriminated-unions)
- [Records](#records)
- [Record key type](#record-key-type)
- [Maps](#maps)
- [Sets](#sets)
- [Intersections](#intersections)
- [Recursive types](#recursive-types)
- [ZodType with ZodEffects](#zodtype-with-zodeffects)
- [JSON type](#json-type)
- [Cyclical objects](#cyclical-objects)
- [Promises](#promises)
- [Instanceof](#instanceof)
- [Functions](#functions)
- [Preprocess](#preprocess)
- [Custom schemas](#custom-schemas)
- [Schema methods](#schema-methods)
- [`.parse`](#parse)
- [`.parseAsync`](#parseasync)
- [`.safeParse`](#safeparse)
- [`.safeParseAsync`](#safeparseasync)
- [`.refine`](#refine)
- [Arguments](#arguments)
- [Customize error path](#customize-error-path)
- [Asynchronous refinements](#asynchronous-refinements)
- [Relationship to transforms](#relationship-to-transforms)
- [`.superRefine`](#superrefine)
- [Abort early](#abort-early)
- [Type refinements](#type-refinements)
- [`.transform`](#transform)
- [Chaining order](#chaining-order)
- [Validating during transform](#validating-during-transform)
- [Relationship to refinements](#relationship-to-refinements)
- [Async transforms](#async-transforms)
- [`.default`](#default)
- [`.describe`](#describe)
- [`.catch`](#catch)
- [`.optional`](#optional)
- [`.nullable`](#nullable)
- [`.nullish`](#nullish)
- [`.array`](#array)
- [`.promise`](#promise)
- [`.or`](#or)
- [`.and`](#and)
- [`.brand`](#brand)
- [`.readonly`](#readonly)
- [`.pipe`](#pipe)
- [You can use `.pipe()` to fix common issues with `z.coerce`.](#you-can-use-pipe-to-fix-common-issues-with-zcoerce)
- [Guides and concepts](#guides-and-concepts)
- [Type inference](#type-inference)
- [Writing generic functions](#writing-generic-functions)
- [Constraining allowable inputs](#constraining-allowable-inputs)
- [Error handling](#error-handling)
- [Error formatting](#error-formatting)
- [Comparison](#comparison)
- [Joi](#joi)
- [Yup](#yup)
- [io-ts](#io-ts)
- [Runtypes](#runtypes)
- [Ow](#ow)
- [Changelog](#changelog)
<br/>
## Introduction
Zod is a TypeScript-first schema declaration and validation library. I'm using the term "schema" to broadly refer to any data type, from a simple `string` to a complex nested object.
Zod is designed to be as developer-friendly as possible. The goal is to eliminate duplicative type declarations. With Zod, you declare a validator _once_ and Zod will automatically infer the static TypeScript type. It's easy to compose simpler types into complex data structures.
Some other great aspects:
- Zero dependencies
- Works in Node.js and all modern browsers
- Tiny: 8kb minified + zipped
- Immutable: methods (e.g. `.optional()`) return a new instance
- Concise, chainable interface
- Functional approach: [parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
- Works with plain JavaScript too! You don't need to use TypeScript.
<br/>
## Sponsors
Sponsorship at any level is appreciated and encouraged. If you built a paid product using Zod, consider one of the [corporate tiers](https://github.com/sponsors/colinhacks).
<br/>
<h3 align="center">Platinum</h3>
<table align="center" style="justify-content: center;align-items: center;display: flex;">
<tr>
<td align="center">
<p></p>
<p>
<a href="https://www.coderabbit.ai/">
<picture height="80px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/eea24edb-ff20-4532-b57c-e8719f455d6d">
<img alt="CodeRabbit logo" height="80px" src="https://github.com/user-attachments/assets/d791bc7d-dc60-4d55-9c31-97779839cb74">
</picture>
</a>
<br />
Cut code review time & bugs in half
<br/>
<a href="https://www.coderabbit.ai/" style="text-decoration:none;">coderabbit.ai</a>
</p>
<p></p>
</td>
</tr>
</table>
<br/>
<h3 align="center">Gold</h3>
<table align="center" style="justify-content: center;align-items: center;display: flex;">
<tr>
<td align="center">
<p></p>
<p>
<a href="https://www.courier.com/?utm_source=zod&utm_campaign=osssponsors">
<picture height="62px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/6b09506a-78de-47e8-a8c1-792efe31910a">
<img alt="Courier logo" height="62px" src="https://github.com/user-attachments/assets/6b09506a-78de-47e8-a8c1-792efe31910a">
</picture>
</a>
<br />
The API platform for sending notifications
<br/>
<a href="https://www.courier.com/?utm_source=zod&utm_campaign=osssponsors" style="text-decoration:none;">courier.com</a>
</p>
<p></p>
</td>
<td align="center">
<p></p>
<p>
<a href="https://liblab.com/?utm_source=zod">
<picture height="62px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/34dfa1a2-ce94-46f4-8902-fbfac3e1a9bc">
<img alt="LibLab" height="62px" src="https://github.com/user-attachments/assets/3de0b617-5137-49c4-b72d-a033cbe602d8">
</picture>
</a>
<br />
Generate better SDKs for your APIs
<br/>
<a href="https://liblab.com/?utm_source=zod" style="text-decoration:none;">liblab.com</a>
</p>
<p></p>
</td>
</tr>
<tr>
<td align="center">
<p></p>
<p>
<a href="https://neon.tech">
<picture height="68px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/83b4b1b1-a9ab-4ae5-a632-56d282f0c444">
<img alt="Neon" height="68px" src="https://github.com/user-attachments/assets/b5799fc8-81ff-4053-a1c3-b29adf85e7a1">
</picture>
</a>
<br />
Serverless Postgres — Ship faster
<br/>
<a href="https://neon.tech" style="text-decoration:none;">neon.tech</a>
</p>
<p></p>
</td>
<td align="center">
<p></p>
<p>
<a href="https://retool.com/?utm_source=github&utm_medium=referral&utm_campaign=zod">
<picture height="45px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/ac65013f-aeb4-48dd-a2ee-41040b69cbe6">
<img alt="Retool" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/5ef4c11b-efeb-4495-90a8-41b83f798600">
</picture>
</a>
<br />
Build AI apps and workflows with <a href="https://retool.com/products/ai?utm_source=github&utm_medium=referral&utm_campaign=zod">Retool AI</a>
<br/>
<a href="https://retool.com/?utm_source=github&utm_medium=referral&utm_campaign=zod" style="text-decoration:none;">retool.com</a>
</p>
<p></p>
</td>
</tr>
<tr>
<td align="center">
<p></p>
<p>
<a href="https://stainless.com">
<picture height="45px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/f20759c1-3e51-49d0-a31e-bbc43abec665">
<img alt="stainless" height="45px" src="https://github.com/colinhacks/zod/assets/3084745/e9444e44-d991-4bba-a697-dbcfad608e47">
</picture>
</a>
<br />
Generate best-in-class SDKs
<br/>
<a href="https://stainless.com" style="text-decoration:none;">stainless.com</a>
</p>
<p></p>
</td>
<td align="center">
<p></p>
<p>
<a href="https://speakeasy.com/?utm_source=zod+docs">
<picture height="40px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/colinhacks/zod/assets/3084745/b1d86601-c7fb-483c-9927-5dc24ce8b737">
<img alt="speakeasy" height="40px" src="https://github.com/colinhacks/zod/assets/3084745/647524a4-22bb-4199-be70-404207a5a2b5">
</picture>
</a>
<br />
SDKs & Terraform providers for your API
<br/>
<a href="https://speakeasy.com/?utm_source=zod+docs" style="text-decoration:none;">speakeasy.com</a>
</p>
<p></p>
</td>
</tr>
</table>
<br/>
<h3 align="center">Silver</h3>
<table align="center" style="justify-content: center;align-items: center;display: flex;">
<tr>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/72055470?s=200&v=4" height="50px;" alt="Nitric" />
<br />
<a style="text-decoration:none;" href="https://nitric.io/" target="_blank">Nitric</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/89474619?s=200&v=4" height="50px;" alt="PropelAuth" />
<br />
<a style="text-decoration:none;" href="https://www.propelauth.com/" target="_blank">PropelAuth</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/80861386?s=200&v=4" height="50px;" alt="Cerbos" />
<br />
<a style="text-decoration:none;" href="https://cerbos.dev/" target="_blank">Cerbos</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/301879?s=200&v=4" height="50px;" alt="Scalar.com logo" />
<br />
<a style="text-decoration:none;" href="https://scalar.com/" target="_blank">Scalar</a>
</td>
</tr><tr>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/95297378?s=200&v=4" height="50px;" alt="Trigger.dev logo" />
<br />
<a style="text-decoration:none;" href="https://trigger.dev" target="_blank">Trigger.dev</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/125754?s=200&v=4" height="50px;" alt="Transloadit logo" />
<br />
<a style="text-decoration:none;" href="https://transloadit.com/?utm_source=zod&utm_medium=refe
rral&utm_campaign=sponsorship&utm_content=github" target="_blank">Transloadit</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/107880645?s=200&v=4" height="50px;" alt="Infisical logo" />
<br />
<a style="text-decoration:none;" href="https://infisical.com" target="_blank">Infisical</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/91036480?s=200&v=4" height="50px;" alt="Whop logo" />
<br />
<a style="text-decoration:none;" href="https://whop.com/" target="_blank">Whop</a>
</td>
</tr><tr>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/36402888?s=200&v=4" height="50px;" alt="CryptoJobsList logo" />
<br />
<a style="text-decoration:none;" href="https://cryptojobslist.com/" target="_blank">CryptoJobsList</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/70170949?s=200&v=4" height="50px;" alt="Plain logo" />
<br />
<a style="text-decoration:none;" href="https://plain.com/" target="_blank">Plain.</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/78935958?s=200&v=4" height="50px;" alt="Inngest logo" />
<br />
<a style="text-decoration:none;" href="https://inngest.com/" target="_blank">Inngest</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/13880908?s=200&v=4" height="50px;" alt="Storyblok CMS" />
<br />
<a style="text-decoration:none;" href="https://storyblok.com/" target="_blank">Storyblok</a>
</td>
</tr><tr>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/16199997?s=200&v=4" height="50px;" alt="Mux logo" />
<br />
<a style="text-decoration:none;" href="https://mux.link/zod" target="_blank">Mux</a>
</td>
<td align="center">
<img src="https://avatars.githubusercontent.com/u/76428554?s=200&v=4" height="50px;" alt="Cybozu logo" />
<br />
<a style="text-decoration:none;" href="https://cybozu.co.jp/index.html" target="_blank">Cybozu</a>
</td>
</tr>
</table>
<br/>
<h3 align="center">Bronze</h3>
<table align="center" style="justify-content: center;align-items: center;display: flex;">
<tr>
<td align="center">
<a href="https://www.val.town/">
<picture width="100%" height="40px">
<source media="(prefers-color-scheme: dark)" srcset="https://github.com/user-attachments/assets/36961d2e-d92e-42af-9031-a41885ece5f4">
<img alt="val town logo" src="https://github.com/user-attachments/assets/95305fc4-4da6-4bf8-aea4-bae8f5893e5d" height="40px">
</picture>
</a>
</td>
<td align="center">
<a href="https://www.route4me.com/">
<img src="https://avatars.githubusercontent.com/u/7936820?s=200&v=4" height="40px;" alt="route4me logo" />
</a>
</td>
<td align="center">
<a href="https://encore.dev">
<img src="https://github.com/colinhacks/zod/assets/3084745/5ad94e73-cd34-4957-9979-37da85fcf9cd" height="40px;" alt="Encore.dev logo" />
</a>
</td>
<td align="center">
<a href="https://www.replay.io/">
<img src="https://avatars.githubusercontent.com/u/60818315?s=200&v=4" height="40px;" alt="Replay.io logo" />
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://www.numeric.io">
<img src="https://i.imgur.com/kTiLtZt.png" height="40px;" alt="Numeric logo" />
</a>
</td>
<td align="center">
<a href="https://marcatopartners.com">
<img src="https://avatars.githubusercontent.com/u/84106192?s=200&v=4" height="40px;" alt="Marcato Partners" />
</a>
</td>
<td align="center">
<a href="https://interval.com">
<img src="https://avatars.githubusercontent.com/u/67802063?s=200&v=4" height="40px;" alt="" />
</a>
</td>
<td align="center">
<a href="https://seasoned.cc">
<img src="https://avatars.githubusercontent.com/u/33913103?s=200&v=4" height="40px;" alt="" />
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://www.bamboocreative.nz/">
<img src="https://avatars.githubusercontent.com/u/41406870?v=4" height="40px;" alt="Bamboo Creative logo" />
</a>
</td>
<td align="center">
<a href="https://github.com/jasonLaster">
<img src="https://avatars.githubusercontent.com/u/254562?v=4" height="40px;" alt="Jason Laster" />
</a>
</td>
</tr>
</table>
<!-- <h3 align="center">Bronze</h3>
<table align="center" style="justify-content: center;align-items: center;display: flex;">
<tr>
<td>Brandon Bayer</td>
<td>Jiří Brabec</td>
<td>Alex Johansson</td>
<td>Fungible Systems</td>
</tr>
<tr>
<td>Adaptable</td>
<td>Avana Wallet</td>
<td>Jason Lengstorf</td>
<td>Global Illumination, Inc.</td>
</tr>
<tr>
<td>MasterBorn</td>
<td>Ryan Palmer</td>
<td>Michael Sweeney</td>
<td>Nextbase</td>
</tr>
<tr>
<td>Remotion</td>
<td>Connor Sinnott</td>
<td>Mohammad-Ali A'râbi</td>
<td>Supatool</td>
</tr>
</table> -->
### Ecosystem
There are a growing number of tools that are built atop or support Zod natively! If you've built a tool or library on top of Zod, tell me about it [on Twitter](https://twitter.com/colinhacks) or [start a Discussion](https://github.com/colinhacks/zod/discussions). I'll add it below and tweet it out.
#### Resources
- [Total TypeScript Zod Tutorial](https://www.totaltypescript.com/tutorials/zod) by [@mattpocockuk](https://twitter.com/mattpocockuk)
- [Fixing TypeScript's Blindspot: Runtime Typechecking](https://www.youtube.com/watch?v=rY_XqfSHock) by [@jherr](https://twitter.com/jherr)
#### API libraries
- [`tRPC`](https://github.com/trpc/trpc): Build end-to-end typesafe APIs without GraphQL.
- [`@anatine/zod-nestjs`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-nestjs): Helper methods for using Zod in a NestJS project.
- [`zod-endpoints`](https://github.com/flock-community/zod-endpoints): Contract-first strictly typed endpoints with Zod. OpenAPI compatible.
- [`zhttp`](https://github.com/evertdespiegeleer/zhttp): An OpenAPI compatible, strictly typed http library with Zod input and response validation.
- [`domain-functions`](https://github.com/SeasonedSoftware/domain-functions/): Decouple your business logic from your framework using composable functions. With first-class type inference from end to end powered by Zod schemas.
- [`@zodios/core`](https://github.com/ecyrbe/zodios): A typescript API client with runtime and compile time validation backed by axios and zod.
- [`express-zod-api`](https://github.com/RobinTail/express-zod-api): Build Express-based APIs with I/O schema validation and custom middlewares.
- [`tapiduck`](https://github.com/sumukhbarve/monoduck/blob/main/src/tapiduck/README.md): End-to-end typesafe JSON APIs with Zod and Express; a bit like tRPC, but simpler.
- [`koa-zod-router`](https://github.com/JakeFenley/koa-zod-router): Create typesafe routes in Koa with I/O validation using Zod.
- [`zod-sockets`](https://github.com/RobinTail/zod-sockets): Zod-powered Socket.IO microframework with I/O validation and built-in AsyncAPI specs
- [`oas-tszod-gen`](https://github.com/inkognitro/oas-tszod-gen): Client SDK code generator to convert OpenApi v3 specifications into TS endpoint caller functions with Zod types.
- [`GQLoom`](https://github.com/modevol-com/gqloom): Weave GraphQL schema and resolvers using Zod.
- [`oRPC`](https://github.com/unnoq/orpc): Typesafe APIs Made Simple
#### Form integrations
- [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form.
- [`TanStack Form`](https://github.com/TanStack/form): Headless, performant, and type-safe form state management for TS/JS, React, Vue, Angular, Solid, and Lit
- [`zod-validation-error`](https://github.com/causaly/zod-validation-error): Generate user-friendly error messages from `ZodError`s.
- [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod.
- [`react-zorm`](https://github.com/esamattis/react-zorm): Standalone `<form>` generation and validation for React using Zod.
- [`zodix`](https://github.com/rileytomasek/zodix): Zod utilities for FormData and URLSearchParams in Remix loaders and actions.
- [`conform`](https://conform.guide/api/zod/parseWithZod): A typesafe form validation library for progressive enhancement of HTML forms. Works with Remix and Next.js.
- [`remix-params-helper`](https://github.com/kiliman/remix-params-helper): Simplify integration of Zod with standard URLSearchParams and FormData for Remix apps.
- [`formik-validator-zod`](https://github.com/glazy/formik-validator-zod): Formik-compliant validator library that simplifies using Zod with Formik.
- [`zod-i18n-map`](https://github.com/aiji42/zod-i18n): Useful for translating Zod error messages.
- [`@modular-forms/solid`](https://github.com/fabian-hiller/modular-forms): Modular form library for SolidJS that supports Zod for validation.
- [`houseform`](https://github.com/crutchcorn/houseform/): A React form library that uses Zod for validation.
- [`sveltekit-superforms`](https://github.com/ciscoheat/sveltekit-superforms): Supercharged form library for SvelteKit with Zod validation.
- [`mobx-zod-form`](https://github.com/MonoidDev/mobx-zod-form): Data-first form builder based on MobX & Zod.
- [`@vee-validate/zod`](https://github.com/logaretm/vee-validate/tree/main/packages/zod): Form library for Vue.js with Zod schema validation.
- [`zod-form-renderer`](https://github.com/thepeaklab/zod-form-renderer): Auto-infer form fields from zod schema and render them with react-hook-form with E2E type safety.
- [`antd-zod`](https://github.com/MrBr/antd-zod): Zod adapter for Ant Design form fields validation.
- [`frrm`](https://github.com/schalkventer/frrm): Tiny 0.5kb Zod-based, HTML form abstraction that goes brr.
#### Zod to X
- [`zod-to-ts`](https://github.com/sachinraja/zod-to-ts): Generate TypeScript definitions from Zod schemas.
- [`zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema): Convert your Zod schemas into [JSON Schemas](https://json-schema.org/).
- [`@anatine/zod-openapi`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-openapi): Converts a Zod schema to an OpenAPI v3.x `SchemaObject`.
- [`zod-fast-check`](https://github.com/DavidTimms/zod-fast-check): Generate `fast-check` arbitraries from Zod schemas.
- [`zod-dto`](https://github.com/kbkk/abitia/tree/master/packages/zod-dto): Generate Nest.js DTOs from a Zod schema.
- [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas.
- [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters.
- [`nestjs-graphql-zod`](https://github.com/incetarik/nestjs-graphql-zod): Generates NestJS GraphQL model classes from Zod schemas. Provides GraphQL method decorators working with Zod schemas.
- [`zod-openapi`](https://github.com/samchungy/zod-openapi): Create full OpenAPI v3.x documentation from Zod schemas.
- [`fastify-zod-openapi`](https://github.com/samchungy/fastify-zod-openapi): Fastify type provider, validation, serialization and @fastify/swagger support for Zod schemas.
- [`typeschema`](https://typeschema.com/): Universal adapter for schema validation.
- [`zodex`](https://github.com/commonbaseapp/zodex): (De)serialization for zod schemas
#### X to Zod
- [`ts-to-zod`](https://github.com/fabien0102/ts-to-zod): Convert TypeScript definitions into Zod schemas.
- [`@runtyping/zod`](https://github.com/johngeorgewright/runtyping): Generate Zod from static types & JSON schema.
- [`json-schema-to-zod`](https://github.com/StefanTerdell/json-schema-to-zod): Convert your [JSON Schemas](https://json-schema.org/) into Zod schemas. [Live demo](https://StefanTerdell.github.io/json-schema-to-zod-react/).
- [`json-to-zod`](https://github.com/rsinohara/json-to-zod): Convert JSON objects into Zod schemas. [Live demo](https://rsinohara.github.io/json-to-zod-react/).
- [`graphql-codegen-typescript-validation-schema`](https://github.com/Code-Hex/graphql-codegen-typescript-validation-schema): GraphQL Code Generator plugin to generate form validation schema from your GraphQL schema.
- [`zod-prisma`](https://github.com/CarterGrimmeisen/zod-prisma): Generate Zod schemas from your Prisma schema.
- [`Supervillain`](https://github.com/Southclaws/supervillain): Generate Zod schemas from your Go structs.
- [`prisma-zod-generator`](https://github.com/omar-dulaimi/prisma-zod-generator): Emit Zod schemas from your Prisma schema.
- [`drizzle-zod`](https://orm.drizzle.team/docs/zod): Emit Zod schemas from your Drizzle schema.
- [`prisma-trpc-generator`](https://github.com/omar-dulaimi/prisma-trpc-generator): Emit fully implemented tRPC routers and their validation schemas using Zod.
- [`zod-prisma-types`](https://github.com/chrishoermann/zod-prisma-types) Create Zod types from your Prisma models.
- [`quicktype`](https://app.quicktype.io/): Convert JSON objects and JSON schemas into Zod schemas.
- [`@sanity-typed/zod`](https://github.com/saiichihashimoto/sanity-typed/tree/main/packages/zod): Generate Zod Schemas from [Sanity Schemas](https://www.sanity.io/docs/schema-types).
- [`java-to-zod`](https://github.com/ivangreene/java-to-zod): Convert POJOs to Zod schemas
- [`Orval`](https://github.com/anymaniax/orval): Generate Zod schemas from OpenAPI schemas
- [`Kubb`](https://github.com/kubb-labs/kubb): Generate SDKs and Zod schemas from your OpenAPI schemas
#### Mocking
- [`@anatine/zod-mock`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-mock): Generate mock data from a Zod schema. Powered by [faker.js](https://github.com/faker-js/faker).
- [`zod-mocking`](https://github.com/dipasqualew/zod-mocking): Generate mock data from your Zod schemas.
- [`zod-fixture`](https://github.com/timdeschryver/zod-fixture): Use your zod schemas to automate the generation of non-relevant test fixtures in a deterministic way.
- [`zocker`](https://zocker.sigrist.dev): Generate plausible mock-data from your schemas.
- [`zodock`](https://github.com/ItMaga/zodock) Generate mock data based on Zod schemas.
- [`zod-schema-faker`](https://github.com/soc221b/zod-schema-faker) Generates mock data from Zod schemas. Powered by [@faker-js/faker](https://github.com/faker-js/faker) and [randexp.js](https://github.com/fent/randexp.js)
#### Powered by Zod
- [`freerstore`](https://github.com/JacobWeisenburger/freerstore): Firestore cost optimizer.
- [`slonik`](https://github.com/gajus/slonik/tree/gajus/add-zod-validation-backwards-compatible#runtime-validation-and-static-type-inference): Node.js Postgres client with strong Zod integration.
- [`schemql`](https://github.com/a2lix/schemql): Enhances your SQL workflow by combining raw SQL with targeted type safety and schema validation.
- [`soly`](https://github.com/mdbetancourt/soly): Create CLI applications with zod.
- [`pastel`](https://github.com/vadimdemedes/pastel): Create CLI applications with react, zod, and ink.
- [`zod-xlsx`](https://github.com/sidwebworks/zod-xlsx): A xlsx based resource validator using Zod schemas.
- [`znv`](https://github.com/lostfictions/znv): Type-safe environment parsing and validation for Node.js with Zod schemas.
- [`zod-config`](https://github.com/alexmarqs/zod-config): Load configurations across multiple sources with flexible adapters, ensuring type safety with Zod.
- [`unplugin-environment`](https://github.com/r17x/js/tree/main/packages/unplugin-environment#readme): A plugin for loading enviroment variables safely with schema validation, simple with virtual module, type-safe with intellisense, and better DX 🔥 🚀 👷. Powered by Zod.
- [`zod-struct`](https://codeberg.org/reesericci/zod-struct): Create runtime-checked structs with Zod.
- [`zod-csv`](https://github.com/bartoszgolebiowski/zod-csv): Validation helpers for zod for parsing CSV data.
- [`fullproduct.dev`](https://fullproduct.dev?identity=freelancers&v=z3): Universal Expo + Next.js App Starter that uses Zod schemas as the single source of truth to keep generated MDX docs, GraphQL, database models, forms, and fetcher functions in sync.
#### Utilities for Zod
- [`zod_utilz`](https://github.com/JacobWeisenburger/zod_utilz): Framework agnostic utilities for Zod.
- [`zod-playground`](https://github.com/marilari88/zod-playground): A tool for learning and testing Zod schema validation functionalities. [Link](https://zod-playground.vercel.app/).
- [`zod-sandbox`](https://github.com/nereumelo/zod-sandbox): Controlled environment for testing zod schemas. [Live demo](https://zod-sandbox.vercel.app/).
- [`zod-dev`](https://github.com/schalkventer/zod-dev): Conditionally disables Zod runtime parsing in production.
- [`zod-accelerator`](https://github.com/duplojs/duplojs-zod-accelerator): Accelerates Zod's throughput up to ~100x.
<br/>
## Installation
### Requirements
- TypeScript 4.5+!
- You must enable `strict` mode in your `tsconfig.json`. This is a best practice for all TypeScript projects.
```ts
// tsconfig.json
{
// ...
"compilerOptions": {
// ...
"strict": true
}
}
```
### From `npm`
```sh
npm install zod # npm
deno add npm:zod # deno
yarn add zod # yarn
bun add zod # bun
pnpm add zod # pnpm
```
Zod also publishes a canary version on every commit. To install the canary:
```sh
npm install zod@canary # npm
deno add npm:zod@canary # deno
yarn add zod@canary # yarn
bun add zod@canary # bun
pnpm add zod@canary # pnpm
```
> The rest of this README assumes you are using npm and importing directly from the `"zod"` package.
<br/>
## Basic usage
Creating a simple string schema
```ts
import { z } from "zod";
// creating a schema for strings
const mySchema = z.string();
// parsing
mySchema.parse("tuna"); // => "tuna"
mySchema.parse(12); // => throws ZodError
// "safe" parsing (doesn't throw error if validation fails)
mySchema.safeParse("tuna"); // => { success: true; data: "tuna" }
mySchema.safeParse(12); // => { success: false; error: ZodError }
```
Creating an object schema
```ts
import { z } from "zod";
const User = z.object({
username: z.string(),
});
User.parse({ username: "Ludwig" });
// extract the inferred type
type User = z.infer<typeof User>;
// { username: string }
```
<br/>
## Primitives
```ts
import { z } from "zod";
// primitive values
z.string();
z.number();
z.bigint();
z.boolean();
z.date();
z.symbol();
// empty types
z.undefined();
z.null();
z.void(); // accepts undefined
// catch-all types
// allows any value
z.any();
z.unknown();
// never type
// allows no values
z.never();
```
<br/>
## Coercion for primitives
Zod now provides a more convenient way to coerce primitive values.
```ts
const schema = z.coerce.string();
schema.parse("tuna"); // => "tuna"
schema.parse(12); // => "12"
```
During the parsing step, the input is passed through the `String()` function, which is a JavaScript built-in for coercing data into strings.
```ts
schema.parse(12); // => "12"
schema.parse(true); // => "true"
schema.parse(undefined); // => "undefined"
schema.parse(null); // => "null"
```
The returned schema is a normal `ZodString` instance so you can use all string methods.
```ts
z.coerce.string().email().min(5);
```
**How coercion works**
All primitive types support coercion. Zod coerces all inputs using the built-in constructors: `String(input)`, `Number(input)`, `new Date(input)`, etc.
```ts
z.coerce.string(); // String(input)
z.coerce.number(); // Number(input)
z.coerce.boolean(); // Boolean(input)
z.coerce.bigint(); // BigInt(input)
z.coerce.date(); // new Date(input)
```
**Note** — Boolean coercion with `z.coerce.boolean()` may not work how you expect. Any [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) value is coerced to `true`, and any [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) value is coerced to `false`.
```ts
const schema = z.coerce.boolean(); // Boolean(input)
schema.parse("tuna"); // => true
schema.parse("true"); // => true
schema.parse("false"); // => true
schema.parse(1); // => true
schema.parse([]); // => true
schema.parse(0); // => false
schema.parse(""); // => false
schema.parse(undefined); // => false
schema.parse(null); // => false
```
For more control over coercion logic, consider using [`z.preprocess`](#preprocess) or [`z.pipe()`](#pipe).
<br/>
## Literals
Literal schemas represent a [literal type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#literal-types), like `"hello world"` or `5`.
```ts
const tuna = z.literal("tuna");
const twelve = z.literal(12);
const twobig = z.literal(2n); // bigint literal
const tru = z.literal(true);
const terrificSymbol = Symbol("terrific");
const terrific = z.literal(terrificSymbol);
// retrieve literal value
tuna.value; // "tuna"
```
> Currently there is no support for Date literals in Zod. If you have a use case for this feature, please file an issue.
<br/>
## Strings
Zod includes a handful of string-specific validations.
```ts
// validations
z.string().max(5);
z.string().min(5);
z.string().length(5);
z.string().email();
z.string().url();
z.string().emoji();
z.string().uuid();
z.string().nanoid();
z.string().cuid();
z.string().cuid2();
z.string().ulid();
z.string().regex(regex);
z.string().includes(string);
z.string().startsWith(string);
z.string().endsWith(string);
z.string().datetime(); // ISO 8601; by default only `Z` timezone allowed
z.string().ip(); // defaults to allow both IPv4 and IPv6
z.string().cidr(); // defaults to allow both IPv4 and IPv6
// transforms
z.string().trim(); // trim whitespace
z.string().toLowerCase(); // toLowerCase
z.string().toUpperCase(); // toUpperCase
// added in Zod 3.23
z.string().date(); // ISO date format (YYYY-MM-DD)
z.string().time(); // ISO time format (HH:mm:ss[.SSSSSS] or HH:mm)
z.string().duration(); // ISO 8601 duration
z.string().base64();
```
> Check out [validator.js](https://github.com/validatorjs/validator.js) for a bunch of other useful string validation functions that can be used in conjunction with [Refinements](#refine).
You can customize some common error messages when creating a string schema.
```ts
const name = z.string({
required_error: "Name is required",
invalid_type_error: "Name must be a string",
});
```
When using validation methods, you can pass in an additional argument to provide a custom error message.
```ts
z.string().min(5, { message: "Must be 5 or more characters long" });
z.string().max(5, { message: "Must be 5 or fewer characters long" });
z.string().length(5, { message: "Must be exactly 5 characters long" });
z.string().email({ message: "Invalid email address" });
z.string().url({ message: "Invalid url" });
z.string().emoji({ message: "Contains non-emoji characters" });
z.string().uuid({ message: "Invalid UUID" });
z.string().includes("tuna", { message: "Must include tuna" });
z.string().startsWith("https://", { message: "Must provide secure URL" });
z.string().endsWith(".com", { message: "Only .com domains allowed" });
z.string().datetime({ message: "Invalid datetime string! Must be UTC." });
z.string().date({ message: "Invalid date string!" });
z.string().time({ message: "Invalid time string!" });
z.string().ip({ message: "Invalid IP address" });
z.string().cidr({ message: "Invalid CIDR" });
```
### Datetimes
As you may have noticed, Zod string includes a few date/time related validations. These validations are regular expression based, so they are not as strict as a full date/time library. However, they are very convenient for validating user input.
The `z.string().datetime()` method enforces ISO 8601; default is no timezone offsets and arbitrary sub-second decimal precision. Seconds may be omitted if precision is not set.
```ts
const datetime = z.string().datetime();
datetime.parse("2020-01-01T00:00:00Z"); // pass
datetime.parse("2020-01-01T00:00:00.123Z"); // pass
datetime.parse("2020-01-01T00:00:00.123456Z"); // pass (arbitrary precision)
datetime.parse("2020-01-01T00:00Z"); // pass (hours and minutes only)
datetime.parse("2020-01-01T00:00:00+02:00"); // fail (no offsets allowed)
```
Timezone offsets can be allowed by setting the `offset` option to `true`.
```ts
const datetime = z.string().datetime({ offset: true });
datetime.parse("2020-01-01T00:00:00+02:00"); // pass
datetime.parse("2020-01-01T00:00+02:00"); // pass
datetime.parse("2020-01-01T00:00:00.123+02:00"); // pass (millis optional)
datetime.parse("2020-01-01T00:00:00.123+0200"); // pass (millis optional)
datetime.parse("2020-01-01T00:00:00.123+02"); // pass (only offset hours)
datetime.parse("2020-01-01T00:00:00Z"); // pass (Z still supported)
```
Allow unqualified (timezone-less) datetimes with the `local` flag.
```ts
const schema = z.string().datetime({ local: true });
schema.parse("2020-01-01T00:00:00"); // pass
schema.parse("2020-01-01T00:00"); // pass
```
You can additionally constrain the allowable `precision`. By default, arbitrary sub-second precision is supported (but optional).
```ts
const datetime = z.string().datetime({ precision: 3 });
datetime.parse("2020-01-01T00:00:00.123Z"); // pass
datetime.parse("2020-01-01T00:00:00Z"); // fail
datetime.parse("2020-01-01T00:00Z"); // fail
datetime.parse("2020-01-01T00:00:00.123456Z"); // fail
```
### Dates
> Added in Zod 3.23
The `z.string().date()` method validates strings in the format `YYYY-MM-DD`.
```ts
const date = z.string().date();
date.parse("2020-01-01"); // pass
date.parse("2020-1-1"); // fail
date.parse("2020-01-32"); // fail
```
### Times
> Added in Zod 3.23
The `z.string().time()` method validates strings in the format `HH:MM` or `HH:MM:SS[.s+]`. The second can include arbitrary decimal precision. It does not allow timezone offsets of any kind.
```ts
const time = z.string().time();
time.parse("00:00:00"); // pass
time.parse("09:52:31"); // pass
time.parse("09:52"); // pass
time.parse("23:59:59.9999999"); // pass (arbitrary precision)
time.parse("00:00:00.123Z"); // fail (no `Z` allowed)
time.parse("00:00:00.123+02:00"); // fail (no offsets allowed)
```
You can set the `precision` option to constrain the allowable decimal precision.
```ts
const time = z.string().time({ precision: 3 });
time.parse("00:00:00.123"); // pass
time.parse("00:00:00.123456"); // fail
time.parse("00:00:00"); // fail
time.parse("00:00"); // fail
```
### IP addresses
By default `.ip()` allows both IPv4 and IPv6.
```ts
const ip = z.string().ip();
ip.parse("192.168.1.1"); // pass
ip.parse("84d5:51a0:9114:1855:4cfa:f2d7:1f12:7003"); // pass
ip.parse("84d5:51a0:9114:1855:4cfa:f2d7:1f12:192.168.1.1"); // pass
ip.parse("256.1.1.1"); // fail
ip.parse("84d5:51a0:9114:gggg:4cfa:f2d7:1f12:7003"); // fail
```
You can additionally set the IP `version`.
```ts
const ipv4 = z.string().ip({ version: "v4" });
ipv4.parse("84d5:51a0:9114:1855:4cfa:f2d7:1f12:7003"); // fail
const ipv6 = z.string().ip({ version: "v6" });
ipv6.parse("192.168.1.1"); // fail
```
### IP ranges (CIDR)
Validate IP address ranges specified with [CIDR notation](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing). By default, `.cidr()` allows both IPv4 and IPv6.
```ts
const cidr = z.string().cidr();
cidr.parse("192.168.0.0/24"); // pass
cidr.parse("2001:db8::/32"); // pass
```
You can specify a version with the `version` parameter.
```ts
const ipv4Cidr = z.string().cidr({ version: "v4" });
ipv4Cidr.parse("84d5:51a0:9114:1855:4cfa:f2d7:1f12:7003"); // fail
const ipv6Cidr = z.string().cidr({ version: "v6" });
ipv6Cidr.parse("192.168.1.1"); // fail
```
<br/>
## Numbers
You can customize certain error messages when creating a number schema.
```ts
const age = z.number({
required_error: "Age is required",
invalid_type_error: "Age must be a number",
});
```
Zod includes a handful of number-specific validations.
```ts
z.number().gt(5);
z.number().gte(5); // alias .min(5)
z.number().lt(5);
z.number().lte(5); // alias .max(5)
z.number().int(); // value must be an integer
z.number().positive(); // > 0
z.number().nonnegative(); // >= 0
z.number().negative(); // < 0
z.number().nonpositive(); // <= 0
z.number().multipleOf(5); // Evenly divisible by 5. Alias .step(5)
z.number().finite(); // value must be finite, not Infinity or -Infinity
z.number().safe(); // value must be between Number.MIN_SAFE_INTEGER and Number.MAX_SAFE_INTEGER
```
Optionally, you can pass in a second argument to provide a custom error message.
```ts
z.number().lte(5, { message: "this👏is👏too👏big" });
```
<br/>
## BigInts
Zod includes a handful of bigint-specific validations.
```ts
z.bigint().gt(5n);
z.bigint().gte(5n); // alias `.min(5n)`
z.bigint().lt(5n);
z.bigint().lte(5n); // alias `.max(5n)`
z.bigint().positive(); // > 0n
z.bigint().nonnegative(); // >= 0n
z.bigint().negative(); // < 0n
z.bigint().nonpositive(); // <= 0n
z.bigint().multipleOf(5n); // Evenly divisible by 5n.
```
<br/>
## NaNs
You can customize certain error messages when creating a nan schema.
```ts
const isNaN = z.nan({
required_error: "isNaN is required",
invalid_type_error: "isNaN must be 'not a number'",
});
```
<br/>
## Booleans
You can customize certain error messages when creating a boolean schema.
```ts
const isActive = z.boolean({
required_error: "isActive is required",
invalid_type_error: "isActive must be a boolean",
});
```
<br/>
## Dates
Use z.date() to validate `Date` instances.
```ts
z.date().safeParse(new Date()); // success: true
z.date().safeParse("2022-01-12T00:00:00.000Z"); // success: false
```
You can customize certain error messages when creating a date schema.
```ts
const myDateSchema = z.date({
required_error: "Please select a date and time",
invalid_type_error: "That's not a date!",
});
```
Zod provides a handful of date-specific validations.
```ts
z.date().min(new Date("1900-01-01"), { message: "Too old" });
z.date().max(new Date(), { message: "Too young!" });
```
**Coercion to Date**
Since [zod 3.20](https://github.com/colinhacks/zod/releases/tag/v3.20), use [`z.coerce.date()`](#coercion-for-primitives) to pass the input through `new Date(input)`.
```ts
const dateSchema = z.coerce.date();
type DateSchema = z.infer<typeof dateSchema>;
// type DateSchema = Date
/* valid dates */
console.log(dateSchema.safeParse("2023-01-10T00:00:00.000Z").success); // true
console.log(dateSchema.safeParse("2023-01-10").success); // true
console.log(dateSchema.safeParse("1/10/23").success); // true
console.log(dateSchema.safeParse(new Date("1/10/23")).success); // true
/* invalid dates */
console.log(dateSchema.safeParse("2023-13-10").success); // false
console.log(dateSchema.safeParse("0000-00-00").success); // false
```
For older zod versions, use [`z.preprocess`](#preprocess) like [described in this thread](https://github.com/colinhacks/zod/discussions/879#discussioncomment-2036276).
<br/>
## Zod enums
```ts
const FishEnum = z.enum(["Salmon", "Tuna", "Trout"]);
type FishEnum = z.infer<typeof FishEnum>;
// 'Salmon' | 'Tuna' | 'Trout'
```
`z.enum` is a Zod-native way to declare a schema with a fixed set of allowable _string_ values. Pass the array of values directly into `z.enum()`. Alternatively, use `as const` to define your enum values as a tuple of strings. See the [const assertion docs](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions) for details.
```ts
const VALUES = ["Salmon", "Tuna", "Trout"] as const;
const FishEnum = z.enum(VALUES);
```
This is not allowed, since Zod isn't able to infer the exact values of each element.
```ts
const fish = ["Salmon", "Tuna", "Trout"];
const FishEnum = z.enum(fish);
```
**`.enum`**
To get autocompletion with a Zod enum, use the `.enum` property of your schema:
```ts
FishEnum.enum.Salmon; // => autocompletes
FishEnum.enum;
/*
=> {
Salmon: "Salmon",
Tuna: "Tuna",
Trout: "Trout",
}
*/
```
You can also retrieve the list of options as a tuple with the `.options` property:
```ts
FishEnum.options; // ["Salmon", "Tuna", "Trout"];
```
**`.exclude/.extract()`**
You can create subsets of a Zod enum with the `.exclude` and `.extract` methods.
```ts
const FishEnum = z.enum(["Salmon", "Tuna", "Trout"]);
const SalmonAndTrout = FishEnum.extract(["Salmon", "Trout"]);
const TunaOnly = FishEnum.exclude(["Salmon", "Trout"]);
```
<br/>
## Native enums
Zod enums are the recommended approach to defining and validating enums. But if you need to validate against an enum from a third-party library (or you don't want to rewrite your existing enums) you can use `z.nativeEnum()`.
**Numeric enums**
```ts
enum Fruits {
Apple,
Banana,
}
const FruitEnum = z.nativeEnum(Fruits);
type FruitEnum = z.infer<typeof FruitEnum>; // Fruits
FruitEnum.parse(Fruits.Apple); // passes
FruitEnum.parse(Fruits.Banana); // passes
FruitEnum.parse(0); // passes
FruitEnum.parse(1); // passes
FruitEnum.parse(3); // fails
```
**String enums**
```ts
enum Fruits {
Apple = "apple",
Banana = "banana",
Cantaloupe, // you can mix numerical and string enums
}
const FruitEnum = z.nativeEnum(Fruits);
type FruitEnum = z.infer<typeof FruitEnum>; // Fruits
FruitEnum.parse(Fruits.Apple); // passes
FruitEnum.parse(Fruits.Cantaloupe); // passes
FruitEnum.parse("apple"); // passes
FruitEnum.parse("banana"); // passes
FruitEnum.parse(0); // passes
FruitEnum.parse("Cantaloupe"); // fails
```
**Const enums**
The `.nativeEnum()` function works for `as const` objects as well. ⚠️ `as const` requires TypeScript 3.4+!
```ts
const Fruits = {
Apple: "apple",
Banana: "banana",
Cantaloupe: 3,
} as const;
const FruitEnum = z.nativeEnum(Fruits);
type FruitEnum = z.infer<typeof FruitEnum>; // "apple" | "banana" | 3
FruitEnum.parse("apple"); // passes
FruitEnum.parse("banana"); // passes
FruitEnum.parse(3); // passes
FruitEnum.parse("Cantaloupe"); // fails
```
You can access the underlying object with the `.enum` property:
```ts
FruitEnum.enum.Apple; // "apple"
```
<br/>
## Optionals
You can make any schema optional with `z.optional()`. This wraps the schema in a `ZodOptional` instance and returns the result.
```ts
const schema = z.optional(z.string());
schema.parse(undefined); // => returns undefined
type A = z.infer<typeof schema>; // string | undefined
```
For convenience, you can also call the `.optional()` method on an existing schema.
```ts
const user = z.object({
username: z.string().optional(),
});
type C = z.infer<typeof user>; // { username?: string | undefined };
```
You can extract the wrapped schema from a `ZodOptional` instance with `.unwrap()`.
```ts
const stringSchema = z.string();
const optionalString = stringSchema.optional();
optionalString.unwrap() === stringSchema; // true
```
<br/>
## Nullables
Similarly, you can create nullable types with `z.nullable()`.
```ts
const nullableString = z.nullable(z.string());
nullableString.parse("asdf"); // => "asdf"
nullableString.parse(null); // => null
```
Or use the `.nullable()` method.
```ts
const E = z.string().nullable(); // equivalent to nullableString
type E = z.infer<typeof E>; // string | null
```
Extract the inner schema with `.unwrap()`.
```ts
const stringSchema = z.string();
const nullableString = stringSchema.nullable();
nullableString.unwrap() === stringSchema; // true
```
<br/>
## Objects
```ts
// all properties are required by default
const Dog = z.object({
name: z.string(),
age: z.number(),
});
// extract the inferred type like this
type Dog = z.infer<typeof Dog>;
// equivalent to:
type Dog = {
name: string;
age: numb