From 3aedba54d7b0f4ba1f5cfca49a1744807dd33c81 Mon Sep 17 00:00:00 2001 From: Colin McDonnell Date: Wed, 11 May 2022 23:14:51 -0700 Subject: [PATCH] Update docs --- docs/README.md | 249 +++++++++++++++++++++++++++++++++++++----------- docs/index.html | 17 +--- 2 files changed, 196 insertions(+), 70 deletions(-) diff --git a/docs/README.md b/docs/README.md index a92ca0c54..486804a86 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,11 +3,11 @@

Zod

+Zod CI status Created by Colin McDonnell License npm stars -coverage discord server

@@ -30,9 +30,9 @@ These docs have been translated into [Chinese](./README_ZH.md). # Table of contents -The full documentation is available both on the [official documentation site](https://zod.js.org/) (recommended) and in `README.md`. + - [What is Zod](#what-is-zod) - [Installation](#installation) @@ -94,8 +94,10 @@ The full documentation is available both on the [official documentation site](ht - [.promise](#promise) - [.or](#or) - [.and](#and) -- [Type inference](#type-inference) -- [Errors](#errors) +- [Guides and concepts](#guides-and-concepts) + - [Type inference](#type-inference) + - [Writing generic functions](#writing-generic-functions) + - [Error handling](#error-handling) - [Comparison](#comparison) - [Joi](#joi) - [Yup](#yup) @@ -114,7 +116,7 @@ Zod is designed to be as developer-friendly as possible. The goal is to eliminat Some other great aspects: - Zero dependencies -- Works in Node.js and browsers (including IE 11) +- Works in Node.js and all modern browsers - Tiny: 8kb minified + zipped - Immutable: methods (i.e. `.optional()`) return a new instance - Concise, chainable interface @@ -123,76 +125,123 @@ Some other great aspects: # Sponsorship -Sponsorship at any level is appreciated and encouraged. Zod is maintained by a solo developer ([hi!](https://twitter.com/colinhacks)). For individual developers, consider the [Cup of Coffee tier](https://github.com/sponsors/colinhacks). If you built a paid product using Zod, consider the [Startup tier](https://github.com/sponsors/colinhacks). You can learn more about the tiers at [github.com/sponsors/colinhacks](https://github.com/sponsors/colinhacks). +Sponsorship at any level is appreciated and encouraged. For individual developers, consider the [Cup of Coffee tier](https://github.com/sponsors/colinhacks). If you built a paid product using Zod, consider one of the [podium tiers](https://github.com/sponsors/colinhacks). -### Sponsors +### Gold - + + + + + +
+ + + + +
+ Astro +
+ astro.build +
+

+ Astro is a new kind of static
+ site builder for the modern web.
+ Powerful developer experience meets
+ lightweight output.

+
+ + + +
+ Glow Wallet +
+ glow.app +
+

Your new favorite +
+ Solana wallet.

+
- + -
+
Deletype -
- deletype.com/ +
+ deletype.com +
+ +### Silver + + + + + - + +
+ + + +
+ Snaplet +
+ snaplet.dev +
+ + Marcato Partners + +
+ Marcato Partners +
+ marcatopartners.com
- - + + + Trip -
- Kevin Simper -
- @kevinsimper +
+ Trip
+ +### Bronze + + + - - - -
-
+
Brandon Bayer
@flybayer, creator of Blitz.js
- - + + -
- Bamboo Creative -
- bamboocreative.nz -
- - - -
- Jeremy Banks -
- github.com/jeremyBanks +
+ Jiří Brabec +
+ @brabeji +
- - Marcato Partners + + -
- Marcato Partners -
- marcatopartners.com +
+ Alex Johansson +
+ @alexdotjs
-_To get your name + Twitter + website here, sponsor Zod at the [Freelancer](https://github.com/sponsors/colinhacks) or [Consultancy](https://github.com/sponsors/colinhacks) tier._ - # Installation To install Zod v3: @@ -241,11 +290,18 @@ There are a growing number of tools that are built atop or support Zod natively! - [`soly`](https://github.com/mdbetancourt/soly): Create CLI applications with zod. - [`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. +- [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas +- [`Supervillain`](https://github.com/Southclaws/supervillain): Generate Zod schemas from your Go structs +- [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters +- [`prisma-zod-generator`](https://github.com/omar-dulaimi/prisma-zod-generator): Emit Zod schemas from your Prisma schema. +- [`prisma-trpc-generator`](https://github.com/omar-dulaimi/prisma-trpc-generator): Emit fully implemented tRPC routers and their validation schemas using Zod. +- [`nestjs-graphql-zod`](https://github.com/incetarik/nestjs-graphql-zod): Generates NestJS GraphQL model classes from Zod schemas dynamically and provides GraphQL method decorators working with Zod schemas. ### Form integrations - [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form - [`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 `
` generation and validation for React using Zod # Basic usage @@ -1133,9 +1189,9 @@ const Category: z.ZodType = BaseCategory.merge( If you want to validate any JSON value, you can use the snippet below. ```ts -type Literal = boolean | null | number | string; -type Json = Literal | { [key: string]: Json } | Json[]; const literalSchema = z.union([z.string(), z.number(), z.boolean(), z.null()]); +type Literal = z.infer; +type Json = Literal | { [key: string]: Json } | Json[]; const jsonSchema: z.ZodType = z.lazy(() => z.union([literalSchema, z.array(jsonSchema), z.record(jsonSchema)]) ); @@ -1300,7 +1356,7 @@ All Zod schemas contain certain methods. Given any Zod schema, you can call its `.parse` method to check `data` is valid. If it is, a value is returned with full type information! Otherwise, an error is thrown. -> IMPORTANT: In Zod 2 and Zod 1.11+, the value returned by `.parse` is a _deep clone_ of the variable you passed in. This was also the case in zod@1.4 and earlier. +> IMPORTANT: The value returned by `.parse` is a _deep clone_ of the variable you passed in. ```ts const stringSchema = z.string(); @@ -1549,7 +1605,26 @@ const stringToNumber = z.string().transform((val) => myString.length); stringToNumber.parse("string"); // => 6 ``` -> ⚠️ Transform functions must not throw. Make sure to use refinements before the transform to make sure the input can be parsed by the transform. +> ⚠️ Transform functions must not throw. Make sure to use refinements before the transform or addIssue within the transform to make sure the input can be parsed by the transform. + +#### Validating during transform + +Similar to `superRefine`, `transform` can optionally take a `ctx`. This allows you to simultaneously +validate and transform the value, which can be simpler than chaining `refine` and `validate`. +When calling `ctx.addIssue` make sure to still return a value of the correct type otherwise the inferred type will include `undefined`. + +```ts +const Strings = z.string().transform((val, ctx) => { + const parsed = parseInt(val); + if (isNaN(parsed)) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Not a number", + }); + } + return parsed; +}); +``` #### Chaining order @@ -1686,7 +1761,9 @@ z.object({ name: z.string() }).and(z.object({ age: z.number() })); // { name: st z.intersection(z.object({ name: z.string() }), z.object({ age: z.number() })); ``` -# Type inference +# Guides and concepts + +## Type inference You can extract the TypeScript type of any schema with `z.infer` . @@ -1715,16 +1792,72 @@ type output = z.output; // number type inferred = z.infer; // number ``` -# Errors +## Writing generic functions + +When attempting to write a functions that accepts a Zod schemas as an input, it's common to try something like this: + +```ts +function makeSchemaOptional(schema: z.ZodType) { + return schema.optional(); +} +``` + +This approach has some issues. The `schema` variable in this function is typed as an instance of `ZodType`, which is an abstract class that all Zod schemas inherit from. This approach loses type information, namely _which subclass_ the input actually is. + +```ts +const arg = makeSchemaOptional(z.string()); +arg.unwrap(); +``` + +A better approach is for the generate parameter to refer to _the schema as a whole_. + +```ts +function makeSchemaOptional(schema: T) { + return schema.optional(); +} +``` + +> `ZodTypeAny` is just a shorthand for `ZodType`, a type that is broad enough to match any Zod schema. + +As you can see, `schema` is now fully and properly typed. + +```ts +const arg = makeSchemaOptional(z.string()); +arg.unwrap(); // ZodString +``` + +### Restricting valid schemas + +The `ZodType` class has three generic parameters. + +```ts +class ZodType< + Output, + Def extends ZodTypeDef = ZodTypeDef, + Input = Output +> { ... } +``` + +By constraining these in your generic input, you can limit what schemas are allowable as inputs to your function: + +```ts +function makeSchemaOptional>(schema: T) { + return schema.optional(); +} + +makeSchemaOptional(z.string()); +// works fine + +makeSchemaOptional(z.number()); +// Error: 'ZodNumber' is not assignable to parameter of type 'ZodType' +``` + +## Error handling Zod provides a subclass of Error called `ZodError`. ZodErrors contain an `issues` array containing detailed information about the validation problems. ```ts -const data = z - .object({ - name: z.string(), - }) - .safeParse({ name: 12 }); +const data = z.object({ name: z.string() }).safeParse({ name: 12 }); if (!data.success) { data.error.issues; diff --git a/docs/index.html b/docs/index.html index d82c9e223..1f2bd52db 100644 --- a/docs/index.html +++ b/docs/index.html @@ -23,24 +23,17 @@ align-items: center; justify-content: space-between; " - > - created by @colinhacks - Docs - Screencasts - + >
- - - + +