zod 3.15.0 → 3.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,13 @@
1
1
  <p align="center">
2
- <img src="logo.svg" width="200px" align="center" />
2
+ <img src="logo.svg" width="200px" align="center" alt="Zod logo" />
3
3
  <h1 align="center">Zod</h1>
4
+ <p align="center">
5
+ ✨ <a href="https://zod.dev">https://zod.dev</a> ✨
6
+ <br/>
7
+ TypeScript-first schema validation with static type inference
8
+ </p>
4
9
  </p>
10
+ <br/>
5
11
  <p align="center">
6
12
  <a href="https://github.com/colinhacks/zod/actions?query=branch%3Amaster"><img src="https://github.com/colinhacks/zod/actions/workflows/test.yml/badge.svg?event=push&branch=master" alt="Zod CI status" /></a>
7
13
  <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>
@@ -12,6 +18,8 @@
12
18
  </p>
13
19
 
14
20
  <div align="center">
21
+ <a href="https://zod.dev">Documentation</a>
22
+ <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
15
23
  <a href="https://discord.gg/RcG33DQJdf">Discord</a>
16
24
  <span>&nbsp;&nbsp;•&nbsp;&nbsp;</span>
17
25
  <a href="https://www.npmjs.com/package/zod">NPM</a>
@@ -24,61 +32,62 @@
24
32
  <br />
25
33
  </div>
26
34
 
35
+ <br/>
27
36
  <br/>
28
37
 
29
- These docs have been translated into [Chinese](./README_ZH.md).
38
+ > These docs have been translated into [Chinese](./README_ZH.md).
30
39
 
31
- # Table of contents
40
+ ## Table of contents
32
41
 
33
42
  <!-- The full documentation is available both on the [official documentation site](https://zod.js.org/) (recommended) and in `README.md`.
34
43
 
35
- ### Go to [zod.js.org](https://zod.js.org) >> -->
44
+ #### Go to [zod.js.org](https://zod.js.org) >> -->
36
45
 
37
- - [What is Zod](#what-is-zod)
46
+ - [Introduction](#introduction)
47
+ - [Sponsors](#sponsors)
48
+ - [Ecosystem](#ecosystem)
38
49
  - [Installation](#installation)
39
- - [Ecosystem](#ecosystem)
40
50
  - [Basic usage](#basic-usage)
41
- - [Defining schemas](#defining-schemas)
42
- - [Primitives](#primitives)
43
- - [Literals](#literals)
44
- - [Strings](#strings)
45
- - [Numbers](#numbers)
46
- - [NaNs](#nans)
47
- - [Booleans](#booleans)
48
- - [Dates](#dates)
49
- - [Zod enums](#zod-enums)
50
- - [Native enums](#native-enums)
51
- - [Optionals](#optionals)
52
- - [Nullables](#nullables)
53
- - [Objects](#objects)
54
- - [.shape](#shape)
55
- - [.extend](#extend)
56
- - [.merge](#merge)
57
- - [.pick/.omit](#pickomit)
58
- - [.partial](#partial)
59
- - [.deepPartial](#deepPartial)
60
- - [.passthrough](#passthrough)
61
- - [.strict](#strict)
62
- - [.strip](#strip)
63
- - [.catchall](#catchall)
64
- - [Arrays](#arrays)
65
- - [.element](#element)
66
- - [.nonempty](#nonempty)
67
- - [.min/.max/.length](#minmaxlength)
68
- - [Tuples](#tuples)
69
- - [Records](#records)
70
- - [Maps](#maps)
71
- - [Sets](#sets)
72
- - [Unions](#unions)
73
- - [Discriminated Unions](#discriminated-unions)
74
- - [Recursive types](#recursive-types)
75
- - [JSON type](#json-type)
76
- - [Cyclical data](#cyclical-objects)
77
- - [Promises](#promises)
78
- - [Instanceof](#instanceof)
79
- - [Function schemas](#function-schemas)
80
- - [Preprocess](#preprocess)
81
- - [Schema methods](#zodtype-methods-and-properties)
51
+ - [Primitives](#primitives)
52
+ - [Literals](#literals)
53
+ - [Strings](#strings)
54
+ - [Numbers](#numbers)
55
+ - [NaNs](#nans)
56
+ - [Booleans](#booleans)
57
+ - [Dates](#dates)
58
+ - [Zod enums](#zod-enums)
59
+ - [Native enums](#native-enums)
60
+ - [Optionals](#optionals)
61
+ - [Nullables](#nullables)
62
+ - [Objects](#objects)
63
+ - [.shape](#shape)
64
+ - [.extend](#extend)
65
+ - [.merge](#merge)
66
+ - [.pick/.omit](#pickomit)
67
+ - [.partial](#partial)
68
+ - [.deepPartial](#deepPartial)
69
+ - [.passthrough](#passthrough)
70
+ - [.strict](#strict)
71
+ - [.strip](#strip)
72
+ - [.catchall](#catchall)
73
+ - [Arrays](#arrays)
74
+ - [.element](#element)
75
+ - [.nonempty](#nonempty)
76
+ - [.min/.max/.length](#minmaxlength)
77
+ - [Tuples](#tuples)
78
+ - [Unions](#unions)
79
+ - [Discriminated Unions](#discriminated-unions)
80
+ - [Records](#records)
81
+ - [Maps](#maps)
82
+ - [Sets](#sets)
83
+ - [Recursive types](#recursive-types)
84
+ - [JSON type](#json-type)
85
+ - [Cyclical data](#cyclical-objects)
86
+ - [Promises](#promises)
87
+ - [Instanceof](#instanceof)
88
+ - [Function schemas](#function-schemas)
89
+ - [Preprocess](#preprocess)
90
+ - [Schema methods](#schema-methods)
82
91
  - [.parse](#parse)
83
92
  - [.parseAsync](#parseasync)
84
93
  - [.safeParse](#safeparse)
@@ -98,6 +107,7 @@ These docs have been translated into [Chinese](./README_ZH.md).
98
107
  - [Type inference](#type-inference)
99
108
  - [Writing generic functions](#writing-generic-functions)
100
109
  - [Error handling](#error-handling)
110
+ - [Error formatting](#error-formatting)
101
111
  - [Comparison](#comparison)
102
112
  - [Joi](#joi)
103
113
  - [Yup](#yup)
@@ -107,7 +117,7 @@ These docs have been translated into [Chinese](./README_ZH.md).
107
117
 
108
118
  <!-- **Zod 2 is coming! Follow [@colinhacks](https://twitter.com/colinhacks) to stay updated and discuss the future of Zod.** -->
109
119
 
110
- # What is Zod
120
+ ## Introduction
111
121
 
112
122
  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.
113
123
 
@@ -123,17 +133,17 @@ Some other great aspects:
123
133
  - Functional approach: [parse, don't validate](https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/)
124
134
  - Works with plain JavaScript too! You don't need to use TypeScript.
125
135
 
126
- # Sponsorship
136
+ ### Sponsors
127
137
 
128
138
  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).
129
139
 
130
- ### Gold
140
+ #### Gold
131
141
 
132
142
  <table>
133
143
  <tr>
134
144
  <td align="center">
135
145
  <a href="https://astro.build/">
136
- <img src="https://avatars.githubusercontent.com/u/44914786?s=200&v=4" width="200px;" alt="" />
146
+ <img src="https://avatars.githubusercontent.com/u/44914786?s=200&v=4" width="200px;" alt="Astro" />
137
147
  </a>
138
148
  <br />
139
149
  <b>Astro</b>
@@ -173,7 +183,7 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
173
183
  </tr>
174
184
  </table>
175
185
 
176
- ### Silver
186
+ #### Silver
177
187
 
178
188
  <table>
179
189
  <tr>
@@ -205,7 +215,7 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
205
215
  </tr>
206
216
  </table>
207
217
 
208
- ### Bronze
218
+ #### Bronze
209
219
 
210
220
  <table>
211
221
  <tr>
@@ -242,34 +252,7 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
242
252
  </tr>
243
253
  </table>
244
254
 
245
- # Installation
246
-
247
- To install Zod v3:
248
-
249
- ```sh
250
- npm install zod
251
- ```
252
-
253
- ⚠️ IMPORTANT: You must enable `strict` mode in your `tsconfig.json`. This is a best practice for all TypeScript projects.
254
-
255
- ```ts
256
- // tsconfig.json
257
- {
258
- // ...
259
- "compilerOptions": {
260
- // ...
261
- "strict": true
262
- }
263
- }
264
- ```
265
-
266
- #### TypeScript requirements
267
-
268
- - Zod 3.x requires TypeScript 4.1+
269
- - Zod 2.x requires TypeScript 3.7+
270
- - Zod 1.x requires TypeScript 3.3+
271
-
272
- # Ecosystem
255
+ ### Ecosystem
273
256
 
274
257
  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.
275
258
 
@@ -284,8 +267,8 @@ There are a growing number of tools that are built atop or support Zod natively!
284
267
  - [`zod-endpoints`](https://github.com/flock-community/zod-endpoints): Contract-first strictly typed endpoints with Zod. OpenAPI compatible.
285
268
  - [`express-zod-api`](https://github.com/RobinTail/express-zod-api): Build Express-based APIs with I/O schema validation and custom middlewares.
286
269
  - [`zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema): Convert your Zod schemas into [JSON Schemas](https://json-schema.org/).
287
- - [`json-schema-to-zod`](https://github.com/StefanTerdell/json-schema-to-zod): Convert your [JSON Schemas](https://json-schema.org/) into Zod schemas. Use it live [here](https://StefanTerdell.github.io/json-schema-to-zod-react/).
288
- - [`json-to-zod`](https://github.com/rsinohara/json-to-zod): Convert JSON objects into Zod schemas. Use it live [here](https://rsinohara.github.io/json-to-zod-react/).
270
+ - [`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/).
271
+ - [`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/).
289
272
  - [`zod-dto`](https://github.com/kbkk/abitia/tree/master/packages/zod-dto): Generate Nest.js DTOs from a Zod schema.
290
273
  - [`soly`](https://github.com/mdbetancourt/soly): Create CLI applications with zod.
291
274
  - [`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
@@ -293,14 +276,44 @@ There are a growing number of tools that are built atop or support Zod natively!
293
276
  - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas
294
277
  - [`Supervillain`](https://github.com/Southclaws/supervillain): Generate Zod schemas from your Go structs
295
278
  - [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters
279
+ - [`prisma-zod-generator`](https://github.com/omar-dulaimi/prisma-zod-generator): Emit Zod schemas from your Prisma schema.
280
+ - [`prisma-trpc-generator`](https://github.com/omar-dulaimi/prisma-trpc-generator): Emit fully implemented tRPC routers and their validation schemas using Zod.
281
+ - [`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.
296
282
 
297
- ### Form integrations
283
+ #### Form integrations
298
284
 
299
285
  - [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form
300
286
  - [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod
301
287
  - [`react-zorm`](https://github.com/esamattis/react-zorm): Standalone `<form>` generation and validation for React using Zod
302
288
 
303
- # Basic usage
289
+ ## Installation
290
+
291
+ To install Zod v3:
292
+
293
+ ```sh
294
+ npm install zod
295
+ ```
296
+
297
+ ⚠️ IMPORTANT: You must enable `strict` mode in your `tsconfig.json`. This is a best practice for all TypeScript projects.
298
+
299
+ ```ts
300
+ // tsconfig.json
301
+ {
302
+ // ...
303
+ "compilerOptions": {
304
+ // ...
305
+ "strict": true
306
+ }
307
+ }
308
+ ```
309
+
310
+ > **TypeScript requirements**
311
+ >
312
+ > - Zod 3.x requires TypeScript 4.1+
313
+ > - Zod 2.x requires TypeScript 3.7+
314
+ > - Zod 1.x requires TypeScript 3.3+
315
+
316
+ ## Basic usage
304
317
 
305
318
  Creating a simple string schema
306
319
 
@@ -335,8 +348,6 @@ type User = z.infer<typeof User>;
335
348
  // { username: string }
336
349
  ```
337
350
 
338
- # Defining schemas
339
-
340
351
  ## Primitives
341
352
 
342
353
  ```ts
@@ -400,9 +411,7 @@ z.string().nonempty({ message: "Can't be empty" });
400
411
 
401
412
  > Check out [validator.js](https://github.com/validatorjs/validator.js) for a bunch of other useful string validation functions.
402
413
 
403
- #### Custom error messages
404
-
405
- You can customize certain errors when creating a string schema.
414
+ You can customize some common errors messages when creating a string schema.
406
415
 
407
416
  ```ts
408
417
  const name = z.string({
@@ -548,7 +557,7 @@ FishEnum.options; // ["Salmon", "Tuna", "Trout"]);
548
557
 
549
558
  ## Native enums
550
559
 
551
- 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()` .
560
+ 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()`.
552
561
 
553
562
  **Numeric enums**
554
563
 
@@ -616,7 +625,7 @@ FruitEnum.enum.Apple; // "apple"
616
625
 
617
626
  ## Optionals
618
627
 
619
- You can make any schema optional with `z.optional()`:
628
+ You can make any schema optional with `z.optional()`. This wraps the schema in a `ZodOptional` instance and returns the result.
620
629
 
621
630
  ```ts
622
631
  const schema = z.optional(z.string());
@@ -625,7 +634,7 @@ schema.parse(undefined); // => returns undefined
625
634
  type A = z.infer<typeof schema>; // string | undefined
626
635
  ```
627
636
 
628
- You can make an existing schema optional with the `.optional()` method:
637
+ For convenience, you can also call the `.optional()` method on an existing schema.
629
638
 
630
639
  ```ts
631
640
  const user = z.object({
@@ -634,7 +643,7 @@ const user = z.object({
634
643
  type C = z.infer<typeof user>; // { username?: string | undefined };
635
644
  ```
636
645
 
637
- #### `.unwrap`
646
+ You can extract the wrapped schema from a `ZodOptional` instance with `.unwrap()`.
638
647
 
639
648
  ```ts
640
649
  const stringSchema = z.string();
@@ -644,7 +653,7 @@ optionalString.unwrap() === stringSchema; // true
644
653
 
645
654
  ## Nullables
646
655
 
647
- Similarly, you can create nullable types like so:
656
+ Similarly, you can create nullable types with `z.nullable()`.
648
657
 
649
658
  ```ts
650
659
  const nullableString = z.nullable(z.string());
@@ -652,14 +661,14 @@ nullableString.parse("asdf"); // => "asdf"
652
661
  nullableString.parse(null); // => null
653
662
  ```
654
663
 
655
- You can make an existing schema nullable with the `nullable` method:
664
+ Or use the `.nullable()` method.
656
665
 
657
666
  ```ts
658
667
  const E = z.string().nullable(); // equivalent to D
659
668
  type E = z.infer<typeof E>; // string | null
660
669
  ```
661
670
 
662
- #### `.unwrap`
671
+ Extract the inner schema with `.unwrap()`.
663
672
 
664
673
  ```ts
665
674
  const stringSchema = z.string();
@@ -815,7 +824,7 @@ const deepPartialUser = user.deepPartial();
815
824
 
816
825
  > Important limitation: deep partials only work as expected in hierarchies of objects, arrays, and tuples.
817
826
 
818
- #### Unrecognized keys
827
+ ### `.passthrough`
819
828
 
820
829
  By default Zod objects schemas strip out unrecognized keys during parsing.
821
830
 
@@ -832,8 +841,6 @@ person.parse({
832
841
  // extraKey has been stripped
833
842
  ```
834
843
 
835
- ### `.passthrough`
836
-
837
844
  Instead, if you want to pass through unknown keys, use `.passthrough()` .
838
845
 
839
846
  ```ts
@@ -846,7 +853,7 @@ person.passthrough().parse({
846
853
 
847
854
  ### `.strict`
848
855
 
849
- You can _disallow_ unknown keys with `.strict()` . If there are any unknown keys in the input, Zod will throw an error.
856
+ By default Zod objects schemas strip out unrecognized keys during parsing. You can _disallow_ unknown keys with `.strict()` . If there are any unknown keys in the input, Zod will throw an error.
850
857
 
851
858
  ```ts
852
859
  const person = z
@@ -983,7 +990,7 @@ For convenience, you can also use the `.or` method:
983
990
  const stringOrNumber = z.string().or(z.number());
984
991
  ```
985
992
 
986
- ### Discriminated unions
993
+ ## Discriminated unions
987
994
 
988
995
  If the union consists of object schemas all identifiable by a common property, it is possible to use
989
996
  the `z.discriminatedUnion` method.
@@ -1029,7 +1036,7 @@ userStore["77d2586b-9e8e-4ecf-8b21-ea7e0530eadd"] = {
1029
1036
  }; // TypeError
1030
1037
  ```
1031
1038
 
1032
- #### A note on numerical keys
1039
+ **A note on numerical keys**
1033
1040
 
1034
1041
  You may have expected `z.record()` to accept two arguments, one for the keys and one for the values. After all, TypeScript's built-in Record type does: `Record<KeyType, ValueType>` . Otherwise, how do you represent the TypeScript type `Record<number, any>` in Zod?
1035
1042
 
@@ -1046,9 +1053,7 @@ for (const key in testMap) {
1046
1053
  // prints: `1: string`
1047
1054
  ```
1048
1055
 
1049
- As you can see, JavaScript automatically casts all object keys to strings under the hood.
1050
-
1051
- Since Zod is trying to bridge the gap between static and runtime types, it doesn't make sense to provide a way of creating a record schema with numerical keys, since there's no such thing as a numerical key in runtime JavaScript.
1056
+ As you can see, JavaScript automatically casts all object keys to strings under the hood. Since Zod is trying to bridge the gap between static and runtime types, it doesn't make sense to provide a way of creating a record schema with numerical keys, since there's no such thing as a numerical key in runtime JavaScript.
1052
1057
 
1053
1058
  ## Maps
1054
1059
 
@@ -1067,7 +1072,7 @@ type NumberSet = z.infer<typeof numberSet>;
1067
1072
  // type NumberSet = Set<number>
1068
1073
  ```
1069
1074
 
1070
- ### `.nonempty/.min/.max/.size`
1075
+ Set schemas can be further contrainted with the following utility methods.
1071
1076
 
1072
1077
  ```ts
1073
1078
  z.set(z.string()).nonempty(); // must contain at least one item
@@ -1078,8 +1083,6 @@ z.set(z.string()).size(5); // must contain 5 items exactly
1078
1083
 
1079
1084
  ## Intersections
1080
1085
 
1081
- <!-- > ⚠️ Intersections are deprecated. If you are trying to merge objects, use the `.merge` method instead. -->
1082
-
1083
1086
  Intersections are useful for creating "logical AND" types. This is useful for intersecting two object types.
1084
1087
 
1085
1088
  ```ts
@@ -1181,7 +1184,7 @@ const Category: z.ZodType<Category> = BaseCategory.merge(
1181
1184
  );
1182
1185
  ``` -->
1183
1186
 
1184
- #### JSON type
1187
+ ### JSON type
1185
1188
 
1186
1189
  If you want to validate any JSON value, you can use the snippet below.
1187
1190
 
@@ -1198,7 +1201,7 @@ jsonSchema.parse(data);
1198
1201
 
1199
1202
  Thanks to [ggoodman](https://github.com/ggoodman) for suggesting this.
1200
1203
 
1201
- #### Cyclical objects
1204
+ ### Cyclical objects
1202
1205
 
1203
1206
  Despite supporting recursive schemas, passing cyclical data into Zod will cause an infinite loop.
1204
1207
 
@@ -1262,7 +1265,7 @@ type myFunction = z.infer<typeof myFunction>;
1262
1265
  // => ()=>unknown
1263
1266
  ```
1264
1267
 
1265
- **Define inputs and output**
1268
+ Define inputs and outputs.
1266
1269
 
1267
1270
  ```ts
1268
1271
  const myFunction = z
@@ -1273,24 +1276,6 @@ type myFunction = z.infer<typeof myFunction>;
1273
1276
  // => (arg0: string, arg1: number)=>boolean
1274
1277
  ```
1275
1278
 
1276
- **Extract the input and output schemas**
1277
- You can extract the parameters and return type of a function schema.
1278
-
1279
- ```ts
1280
- myFunction.parameters();
1281
- // => ZodTuple<[ZodString, ZodNumber]>
1282
-
1283
- myFunction.returnType();
1284
- // => ZodBoolean
1285
- ```
1286
-
1287
- <!-- `z.function()` accepts two arguments:
1288
-
1289
- * `args: ZodTuple` The first argument is a tuple (created with `z.tuple([...])` and defines the schema of the arguments to your function. If the function doesn't accept arguments, you can pass an empty tuple (`z.tuple([])`).
1290
- * `returnType: any Zod schema` The second argument is the function's return type. This can be any Zod schema. -->
1291
-
1292
- > You can use the special `z.void()` option if your function doesn't return anything. This will let Zod properly infer the type of void-returning functions. (Void-returning functions actually return undefined.)
1293
-
1294
1279
  <!--
1295
1280
 
1296
1281
  ``` ts
@@ -1319,7 +1304,9 @@ trimmedLength("sandwich"); // => 8
1319
1304
  trimmedLength(" asdf "); // => 4
1320
1305
  ```
1321
1306
 
1322
- If you only care about validating inputs, that's fine:
1307
+ If you only care about validating inputs, just don't call the `.returns()` method. The output type will be inferred from the implementation.
1308
+
1309
+ > You can use the special `z.void()` option if your function doesn't return anything. This will let Zod properly infer the type of void-returning functions. (Void-returning functions actually return undefined.)
1323
1310
 
1324
1311
  ```ts
1325
1312
  const myFunction = z
@@ -1331,6 +1318,21 @@ const myFunction = z
1331
1318
  myFunction; // (arg: string)=>number[]
1332
1319
  ```
1333
1320
 
1321
+ Extract the input and output schemas from a function schema.
1322
+
1323
+ ```ts
1324
+ myFunction.parameters();
1325
+ // => ZodTuple<[ZodString, ZodNumber]>
1326
+
1327
+ myFunction.returnType();
1328
+ // => ZodBoolean
1329
+ ```
1330
+
1331
+ <!-- `z.function()` accepts two arguments:
1332
+
1333
+ * `args: ZodTuple` The first argument is a tuple (created with `z.tuple([...])` and defines the schema of the arguments to your function. If the function doesn't accept arguments, you can pass an empty tuple (`z.tuple([])`).
1334
+ * `returnType: any Zod schema` The second argument is the function's return type. This can be any Zod schema. -->
1335
+
1334
1336
  ## Preprocess
1335
1337
 
1336
1338
  Typically Zod operates under a "parse then transform" paradigm. Zod validates the input first, then passes it through a chain of transformation functions. (For more information about transforms, read the [.transform docs](#transform).)
@@ -1343,7 +1345,7 @@ const castToString = z.preprocess((val) => String(val), z.string());
1343
1345
 
1344
1346
  This returns a `ZodEffects` instance. `ZodEffects` is a wrapper class that contains all logic pertaining to preprocessing, refinements, and transforms.
1345
1347
 
1346
- # ZodType: methods and properties
1348
+ ## Schema methods
1347
1349
 
1348
1350
  All Zod schemas contain certain methods.
1349
1351
 
@@ -1353,7 +1355,7 @@ All Zod schemas contain certain methods.
1353
1355
 
1354
1356
  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.
1355
1357
 
1356
- > 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.
1358
+ > IMPORTANT: The value returned by `.parse` is a _deep clone_ of the variable you passed in.
1357
1359
 
1358
1360
  ```ts
1359
1361
  const stringSchema = z.string();
@@ -1368,8 +1370,11 @@ stringSchema.parse(12); // throws Error('Non-string type: number');
1368
1370
  If you use asynchronous [refinements](#refine) or [transforms](#transform) (more on those later), you'll need to use `.parseAsync`
1369
1371
 
1370
1372
  ```ts
1371
- const stringSchema = z.string().refine(async (val) => val.length > 20);
1372
- const value = await stringSchema.parseAsync("hello"); // => hello
1373
+ const stringSchema1 = z.string().refine(async (val) => val.length < 20);
1374
+ const value1 = await stringSchema.parseAsync("hello"); // => hello
1375
+
1376
+ const stringSchema2 = z.string().refine(async (val) => val.length > 20);
1377
+ const value2 = await stringSchema.parseAsync("hello"); // => throws
1373
1378
  ```
1374
1379
 
1375
1380
  ### `.safeParse`
@@ -1602,7 +1607,7 @@ const stringToNumber = z.string().transform((val) => myString.length);
1602
1607
  stringToNumber.parse("string"); // => 6
1603
1608
  ```
1604
1609
 
1605
- > ⚠️ Transform functions must not throw. Make sure to use refinements before the transform to make sure the input can be parsed by the transform.
1610
+ > ⚠️ 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.
1606
1611
 
1607
1612
  #### Chaining order
1608
1613
 
@@ -1617,14 +1622,33 @@ const emailToDomain = z
1617
1622
  emailToDomain.parse("colinhacks@example.com"); // => example.com
1618
1623
  ```
1619
1624
 
1625
+ #### Validating during transform
1626
+
1627
+ 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`.
1628
+
1629
+ ```ts
1630
+ const Strings = z.string().transform((val, ctx) => {
1631
+ const parsed = parseInt(val);
1632
+ if (isNaN(parsed)) {
1633
+ ctx.addIssue({
1634
+ code: z.ZodIssueCode.custom,
1635
+ message: "Not a number",
1636
+ });
1637
+ }
1638
+ return parsed;
1639
+ });
1640
+ ```
1641
+
1620
1642
  #### Relationship to refinements
1621
1643
 
1622
- Transforms and refinements can be interleaved:
1644
+ Transforms and refinements can be interleaved. These will be executed in the order they are declared.
1623
1645
 
1624
1646
  ```ts
1625
1647
  z.string()
1626
- .transform((val) => val.length)
1627
- .refine((val) => val > 25);
1648
+ .transform((val) => val.toUpperCase())
1649
+ .refine((val) => val.length > 15)
1650
+ .transform((val) => `Hello ${val}`)
1651
+ .refine((val) => val.indexOf("!") === -1);
1628
1652
  ```
1629
1653
 
1630
1654
  #### Async transforms
@@ -1686,7 +1710,7 @@ z.nullable(z.string());
1686
1710
 
1687
1711
  ### `.nullish`
1688
1712
 
1689
- A convenience method that returns a "nullish" version of a schema. Nullish schemas will accept both `undefined` and `null`. Read more about the concept of "nullish" [here](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing).
1713
+ A convenience method that returns a "nullish" version of a schema. Nullish schemas will accept both `undefined` and `null`. Read more about the concept of "nullish" [in the TypeScript 3.7 release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing).
1690
1714
 
1691
1715
  ```ts
1692
1716
  const nullishString = z.string().nullish(); // string | null | undefined
@@ -1739,9 +1763,9 @@ z.object({ name: z.string() }).and(z.object({ age: z.number() })); // { name: st
1739
1763
  z.intersection(z.object({ name: z.string() }), z.object({ age: z.number() }));
1740
1764
  ```
1741
1765
 
1742
- # Guides and concepts
1766
+ ## Guides and concepts
1743
1767
 
1744
- ## Type inference
1768
+ ### Type inference
1745
1769
 
1746
1770
  You can extract the TypeScript type of any schema with `z.infer<typeof mySchema>` .
1747
1771
 
@@ -1753,7 +1777,7 @@ const u: A = 12; // TypeError
1753
1777
  const u: A = "asdf"; // compiles
1754
1778
  ```
1755
1779
 
1756
- #### What about transforms?
1780
+ **What about transforms?**
1757
1781
 
1758
1782
  In reality each Zod schema internally tracks **two** types: an input and an output. For most schemas (e.g. `z.string()`) these two are the same. But once you add transforms into the mix, these two values can diverge. For instance `z.string().transform(val => val.length)` has an input of `string` and an output of `number`.
1759
1783
 
@@ -1770,7 +1794,7 @@ type output = z.output<typeof stringToNumber>; // number
1770
1794
  type inferred = z.infer<typeof stringToNumber>; // number
1771
1795
  ```
1772
1796
 
1773
- ## Writing generic functions
1797
+ ### Writing generic functions
1774
1798
 
1775
1799
  When attempting to write a functions that accepts a Zod schemas as an input, it's common to try something like this:
1776
1800
 
@@ -1804,13 +1828,13 @@ const arg = makeSchemaOptional(z.string());
1804
1828
  arg.unwrap(); // ZodString
1805
1829
  ```
1806
1830
 
1807
- ### Restricting valid schemas
1831
+ #### Constraining allowable inputs
1808
1832
 
1809
1833
  The `ZodType` class has three generic parameters.
1810
1834
 
1811
1835
  ```ts
1812
1836
  class ZodType<
1813
- Output,
1837
+ Output = any,
1814
1838
  Def extends ZodTypeDef = ZodTypeDef,
1815
1839
  Input = Output
1816
1840
  > { ... }
@@ -1830,12 +1854,16 @@ makeSchemaOptional(z.number());
1830
1854
  // Error: 'ZodNumber' is not assignable to parameter of type 'ZodType<string, ZodTypeDef, string>'
1831
1855
  ```
1832
1856
 
1833
- ## Error handling
1857
+ ### Error handling
1834
1858
 
1835
1859
  Zod provides a subclass of Error called `ZodError`. ZodErrors contain an `issues` array containing detailed information about the validation problems.
1836
1860
 
1837
1861
  ```ts
1838
- const data = z.object({ name: z.string() }).safeParse({ name: 12 });
1862
+ const data = z
1863
+ .object({
1864
+ name: z.string(),
1865
+ })
1866
+ .safeParse({ name: 12 });
1839
1867
 
1840
1868
  if (!data.success) {
1841
1869
  data.error.issues;
@@ -1851,20 +1879,31 @@ if (!data.success) {
1851
1879
  }
1852
1880
  ```
1853
1881
 
1854
- #### Error formatting
1882
+ > For detailed information about the possible error codes and how to customize error messages, check out the dedicated error handling guide: [ERROR_HANDLING.md](ERROR_HANDLING.md)
1883
+
1884
+ ### Error formatting
1855
1885
 
1856
1886
  You can use the `.format()` method to convert this error into a nested object.
1857
1887
 
1858
1888
  ```ts
1859
- data.error.format();
1860
- /* {
1861
- name: { _errors: [ 'Expected string, received number' ] }
1862
- } */
1863
- ```
1889
+ const data = z
1890
+ .object({
1891
+ name: z.string(),
1892
+ })
1893
+ .safeParse({ name: 12 });
1864
1894
 
1865
- For detailed information about the possible error codes and how to customize error messages, check out the dedicated error handling guide: [ERROR_HANDLING.md](ERROR_HANDLING.md)
1895
+ if (!data.success) {
1896
+ const formatted = data.error.format();
1897
+ /* {
1898
+ name: { _errors: [ 'Expected string, received number' ] }
1899
+ } */
1866
1900
 
1867
- # Comparison
1901
+ formatted.name?._errors;
1902
+ // => ["Expected string, received number"]
1903
+ }
1904
+ ```
1905
+
1906
+ ## Comparison
1868
1907
 
1869
1908
  There are a handful of other widely-used validation libraries, but all of them have certain design limitations that make for a non-ideal developer experience.
1870
1909
 
@@ -1916,20 +1955,18 @@ Branded -->
1916
1955
  * Missing support for parsing cyclical data (maybe)
1917
1956
  * Missing error customization -->
1918
1957
 
1919
- #### Joi
1958
+ **Joi**
1920
1959
 
1921
1960
  [https://github.com/hapijs/joi](https://github.com/hapijs/joi)
1922
1961
 
1923
1962
  Doesn't support static type inference 😕
1924
1963
 
1925
- #### Yup
1964
+ **Yup**
1926
1965
 
1927
1966
  [https://github.com/jquense/yup](https://github.com/jquense/yup)
1928
1967
 
1929
1968
  Yup is a full-featured library that was implemented first in vanilla JS, and later rewritten in TypeScript.
1930
1969
 
1931
- Differences
1932
-
1933
1970
  - Supports casting and transforms
1934
1971
  - All object fields are optional by default
1935
1972
  - Missing object methods: (partial, deepPartial)
@@ -1940,7 +1977,7 @@ Differences
1940
1977
 
1941
1978
  <!-- ¹Yup has a strange interpretation of the word `required`. Instead of meaning "not undefined", Yup uses it to mean "not empty". So `yup.string().required()` will not accept an empty string, and `yup.array(yup.string()).required()` will not accept an empty array. Instead, Yup us Zod arrays there is a dedicated `.nonempty()` method to indicate this, or you can implement it with a custom refinement. -->
1942
1979
 
1943
- #### io-ts
1980
+ **io-ts**
1944
1981
 
1945
1982
  [https://github.com/gcanti/io-ts](https://github.com/gcanti/io-ts)
1946
1983
 
@@ -1991,7 +2028,7 @@ This more declarative API makes schema definitions vastly more concise.
1991
2028
  - Missing promise schemas
1992
2029
  - Missing function schemas
1993
2030
 
1994
- #### Runtypes
2031
+ **Runtypes**
1995
2032
 
1996
2033
  [https://github.com/pelotom/runtypes](https://github.com/pelotom/runtypes)
1997
2034
 
@@ -2004,7 +2041,7 @@ Good type inference support, but limited options for object type masking (no `.p
2004
2041
  - Missing promise schemas
2005
2042
  - Missing error customization
2006
2043
 
2007
- #### Ow
2044
+ **Ow**
2008
2045
 
2009
2046
  [https://github.com/sindresorhus/ow](https://github.com/sindresorhus/ow)
2010
2047
 
@@ -2012,6 +2049,6 @@ Ow is focused on function input validation. It's a library that makes it easy to
2012
2049
 
2013
2050
  If you want to validate function inputs, use function schemas in Zod! It's a much simpler approach that lets you reuse a function type declaration without repeating yourself (namely, copy-pasting a bunch of ow assertions at the beginning of every function). Also Zod lets you validate your return types as well, so you can be sure there won't be any unexpected data passed downstream.
2014
2051
 
2015
- # Changelog
2052
+ ## Changelog
2016
2053
 
2017
2054
  View the changelog at [CHANGELOG.md](CHANGELOG.md)