zod 3.19.1 → 3.20.0-beta.0

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
@@ -83,6 +83,7 @@
83
83
  - [Records](#records)
84
84
  - [Maps](#maps)
85
85
  - [Sets](#sets)
86
+ - [Intersections](#intersections)
86
87
  - [Recursive types](#recursive-types)
87
88
  - [JSON type](#json-type)
88
89
  - [Cyclical data](#cyclical-objects)
@@ -99,6 +100,7 @@
99
100
  - [.superRefine](#superRefine)
100
101
  - [.transform](#transform)
101
102
  - [.default](#default)
103
+ - [.catch](#catch)
102
104
  - [.optional](#optional)
103
105
  - [.nullable](#nullable)
104
106
  - [.nullish](#nullish)
@@ -177,13 +179,22 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
177
179
  <tr>
178
180
  <td align="center">
179
181
  <a href="https://deletype.com/">
180
- <img src="https://avatars0.githubusercontent.com/u/15068039?s=200&v=4" width="200px;" alt="" />
182
+ <img src="https://avatars0.githubusercontent.com/u/15068039?s=200&v=4" width="200px;" alt="Deletype logo" />
181
183
  </a>
182
184
  <br />
183
185
  <b>Deletype</b>
184
186
  <br />
185
187
  <a href="https://deletype.com">deletype.com</a>
186
188
  </td>
189
+ <td align="center">
190
+ <a href="https://proxy.com/">
191
+ <img src="https://avatars.githubusercontent.com/u/14321439?s=200&v=4" width="200px;" alt="Proxy logo" />
192
+ </a>
193
+ <br />
194
+ <b>Proxy</b>
195
+ <br />
196
+ <a href="https://proxy.com">proxy.com</a>
197
+ </td>
187
198
  </tr>
188
199
  </table>
189
200
 
@@ -191,16 +202,27 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
191
202
 
192
203
  <table>
193
204
  <tr>
205
+ <td align="center" colspan="2">
206
+ <a href="https://www.numeric.io">
207
+ <img src="https://i.imgur.com/kTiLtZt.png" width="250px;" alt="Numeric logo" />
208
+ </a>
209
+ <br />
210
+ <b>Numeric</b>
211
+ <br />
212
+ <a href="https://www.numeric.io">numeric.io</a>
213
+ </td>
194
214
  <td align="center">
195
215
  <a href="https://snaplet.dev">
196
- <img src="https://avatars.githubusercontent.com/u/69029941?s=200&v=4" width="150px;" alt="" />
216
+ <img src="https://avatars.githubusercontent.com/u/69029941?s=200&v=4" width="150px;" alt="Snaplet logo" />
197
217
  </a>
198
218
  <br />
199
219
  <b>Snaplet</b>
200
220
  <br />
201
221
  <a href="https://snaplet.dev">snaplet.dev</a>
202
222
  </td>
203
- <td align="center">
223
+ </tr>
224
+ <tr>
225
+ <td align="center">
204
226
  <a href="https://marcatopartners.com/">
205
227
  <img src="https://avatars.githubusercontent.com/u/84106192?s=200&v=4" width="150px;" alt="Marcato Partners" />
206
228
  </a>
@@ -210,14 +232,14 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
210
232
  <a href="https://marcatopartners.com/">marcatopartners.com</a>
211
233
  </td>
212
234
  <td align="center">
213
- <a href="https://github.com/macandcheese-spaghetticode">
214
- <img src="https://avatars.githubusercontent.com/u/76997592?v=4" width="150px;" alt="Trip" />
235
+ <a href="https://interval.com">
236
+ <img src="https://avatars.githubusercontent.com/u/67802063?s=200&v=4" width="150px;" alt="" />
215
237
  </a>
216
238
  <br />
217
- <b>Trip</b>
239
+ <b>Interval</b>
240
+ <br />
241
+ <a href="https://interval.com">interval.com</a>
218
242
  </td>
219
- </tr>
220
- <tr>
221
243
  <td align="center">
222
244
  <a href="https://seasoned.cc">
223
245
  <img src="https://avatars.githubusercontent.com/u/33913103?s=200&v=4" width="150px;" alt="" />
@@ -227,14 +249,16 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
227
249
  <br />
228
250
  <a href="https://seasoned.cc">seasoned.cc</a>
229
251
  </td>
252
+ </tr>
253
+ <tr>
230
254
  <td align="center">
231
- <a href="https://interval.com">
232
- <img src="https://avatars.githubusercontent.com/u/67802063?s=200&v=4" width="150px;" alt="" />
255
+ <a href="https://www.bamboocreative.nz/">
256
+ <img src="https://avatars.githubusercontent.com/u/41406870?v=4" width="150px;" alt="Bamboo Creative logo" />
233
257
  </a>
234
258
  <br />
235
- <b>Interval</b>
259
+ <b>Bamboo Creative</b>
236
260
  <br />
237
- <a href="https://interval.com">interval.com</a>
261
+ <a href="https://www.bamboocreative.nz">bamboocreative.nz</a>
238
262
  </td>
239
263
  </tr>
240
264
  </table>
@@ -275,6 +299,16 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
275
299
  </td>
276
300
  </tr>
277
301
  <tr>
302
+ <td align="center">
303
+ <a href="https://fungible.systems/">
304
+ <img src="https://avatars.githubusercontent.com/u/80220121?s=200&v=4" width="100px;" alt="Fungible Systems logo"/>
305
+ </a>
306
+ <br />
307
+ <b>Fungible Systems</b>
308
+ <br/>
309
+ <a href="https://fungible.systems/">fungible.systems</a>
310
+ <br />
311
+ </td>
278
312
  <td align="center">
279
313
  <a href="https://adaptable.io/">
280
314
  <img src="https://avatars.githubusercontent.com/u/60378268?s=200&v=4" width="100px;" alt=""/>
@@ -303,46 +337,67 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
303
337
 
304
338
  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.
305
339
 
340
+ #### Resources
341
+
342
+ - [Total TypeScript Zod Tutorial](https://www.totaltypescript.com/tutorials/zod) by [@mattpocockuk](https://twitter.com/mattpocockuk)
343
+ - [Fixing TypeScript's Blindspot: Runtime Typechecking](https://www.youtube.com/watch?v=rY_XqfSHock) by [@jherr](https://twitter.com/jherr)
344
+
345
+ #### API libraries
346
+
306
347
  - [`tRPC`](https://github.com/trpc/trpc): Build end-to-end typesafe APIs without GraphQL.
307
- - [`ts-to-zod`](https://github.com/fabien0102/ts-to-zod): Convert TypeScript definitions into Zod schemas.
308
- - [`zod-to-ts`](https://github.com/sachinraja/zod-to-ts): Generate TypeScript definitions from Zod schemas.
309
- - [`@anatine/zod-openapi`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-openapi): Converts a Zod schema to an OpenAPI v3.x `SchemaObject`.
310
- - [`@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/Marak/Faker.js).
311
348
  - [`@anatine/zod-nestjs`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-nestjs): Helper methods for using Zod in a NestJS project.
312
- - [`zod-mocking`](https://github.com/dipasqualew/zod-mocking): Generate mock data from your Zod schemas.
313
- - [`zod-fast-check`](https://github.com/DavidTimms/zod-fast-check): Generate `fast-check` arbitraries from Zod schemas.
314
349
  - [`zod-endpoints`](https://github.com/flock-community/zod-endpoints): Contract-first strictly typed endpoints with Zod. OpenAPI compatible.
350
+ - [`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.
351
+ - [`@zodios/core`](https://github.com/ecyrbe/zodios): A typescript API client with runtime and compile time validation backed by axios and zod.
315
352
  - [`express-zod-api`](https://github.com/RobinTail/express-zod-api): Build Express-based APIs with I/O schema validation and custom middlewares.
353
+
354
+ #### Form integrations
355
+
356
+ - [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form.
357
+ - [`zod-validation-error`](https://github.com/causaly/zod-validation-error): Generate user-friendly error messages from `ZodError`s
358
+ - [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod.
359
+ - [`react-zorm`](https://github.com/esamattis/react-zorm): Standalone `<form>` generation and validation for React using Zod.
360
+ - [`zodix`](https://github.com/rileytomasek/zodix): Zod utilities for FormData and URLSearchParams in Remix loaders and actions.
361
+
362
+ #### Zod to X
363
+
364
+ - [`zod-to-ts`](https://github.com/sachinraja/zod-to-ts): Generate TypeScript definitions from Zod schemas.
316
365
  - [`zod-to-json-schema`](https://github.com/StefanTerdell/zod-to-json-schema): Convert your Zod schemas into [JSON Schemas](https://json-schema.org/).
366
+ - [`@anatine/zod-openapi`](https://github.com/anatine/zod-plugins/tree/main/packages/zod-openapi): Converts a Zod schema to an OpenAPI v3.x `SchemaObject`.
367
+ - [`zod-fast-check`](https://github.com/DavidTimms/zod-fast-check): Generate `fast-check` arbitraries from Zod schemas.
368
+ - [`zod-dto`](https://github.com/kbkk/abitia/tree/master/packages/zod-dto): Generate Nest.js DTOs from a Zod schema.
369
+ - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas.
370
+ - [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters.
371
+ - [`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.
372
+
373
+ #### X to Zod
374
+
375
+ - [`ts-to-zod`](https://github.com/fabien0102/ts-to-zod): Convert TypeScript definitions into Zod schemas.
376
+ - [`@runtyping/zod`](https://github.com/johngeorgewright/runtyping/tree/master/packages/zod): Generate Zod from static types & JSON schema.
317
377
  - [`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/).
318
378
  - [`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/).
319
- - [`zod-dto`](https://github.com/kbkk/abitia/tree/master/packages/zod-dto): Generate Nest.js DTOs from a Zod schema.
320
- - [`soly`](https://github.com/mdbetancourt/soly): Create CLI applications with zod.
321
379
  - [`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
322
380
  - [`zod-prisma`](https://github.com/CarterGrimmeisen/zod-prisma): Generate Zod schemas from your Prisma schema.
323
- - [`fastify-type-provider-zod`](https://github.com/turkerdev/fastify-type-provider-zod): Create Fastify type providers from Zod schemas
324
- - [`Supervillain`](https://github.com/Southclaws/supervillain): Generate Zod schemas from your Go structs
325
- - [`zod-to-openapi`](https://github.com/asteasolutions/zod-to-openapi): Generate full OpenAPI (Swagger) docs from Zod, including schemas, endpoints & parameters
381
+ - [`Supervillain`](https://github.com/Southclaws/supervillain): Generate Zod schemas from your Go structs.
326
382
  - [`prisma-zod-generator`](https://github.com/omar-dulaimi/prisma-zod-generator): Emit Zod schemas from your Prisma schema.
327
383
  - [`prisma-trpc-generator`](https://github.com/omar-dulaimi/prisma-trpc-generator): Emit fully implemented tRPC routers and their validation schemas using Zod.
328
- - [`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.
329
- - [`zod-xlsx`](https://github.com/sidwebworks/zod-xlsx): A xlsx based resource validator using Zod schemas.
330
- - [`remix-domains`](https://github.com/SeasonedSoftware/remix-domains/): Improves end-to-end type safety in [Remix](https://remix.run/) by leveraging Zod to parse the framework's inputs such as FormData, URLSearchParams, etc.
331
- - [`@zodios/core`](https://github.com/ecyrbe/zodios): A typescript API client with runtime and compile time validation backed by axios and zod.
332
- - [`@runtyping/zod`](https://github.com/johngeorgewright/runtyping/tree/master/packages/zod): Generate zod from static types & JSON schema.
333
- - [`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
334
384
 
335
- #### Form integrations
385
+ #### Mocking
336
386
 
337
- - [`react-hook-form`](https://github.com/react-hook-form/resolvers#zod): A first-party Zod resolver for React Hook Form
338
- - [`zod-formik-adapter`](https://github.com/robertLichtnow/zod-formik-adapter): A community-maintained Formik adapter for Zod
339
- - [`react-zorm`](https://github.com/esamattis/react-zorm): Standalone `<form>` generation and validation for React using Zod
387
+ - [`@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/Marak/Faker.js).
388
+ - [`zod-mocking`](https://github.com/dipasqualew/zod-mocking): Generate mock data from your Zod schemas.
389
+
390
+ #### Powered by Zod
391
+
392
+ - [`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.
393
+ - [`soly`](https://github.com/mdbetancourt/soly): Create CLI applications with zod.
394
+ - [`zod-xlsx`](https://github.com/sidwebworks/zod-xlsx): A xlsx based resource validator using Zod schemas.
340
395
 
341
396
  ## Installation
342
397
 
343
398
  ### Requirements
344
399
 
345
- - TypeScript 4.1+!
400
+ - TypeScript 4.5+!
346
401
  - You must enable `strict` mode in your `tsconfig.json`. This is a best practice for all TypeScript projects.
347
402
 
348
403
  ```ts
@@ -356,17 +411,16 @@ There are a growing number of tools that are built atop or support Zod natively!
356
411
  }
357
412
  ```
358
413
 
359
- ### Node/npm
360
-
361
- To install Zod v3:
414
+ ### From `npm` (Node/Bun)
362
415
 
363
416
  ```sh
364
417
  npm install zod # npm
365
418
  yarn add zod # yarn
419
+ bun add zod # bun
366
420
  pnpm add zod # pnpm
367
421
  ```
368
422
 
369
- ### Deno
423
+ ### From `deno.land/x` (Deno)
370
424
 
371
425
  Unlike Node, Deno relies on direct URL imports instead of a package manager like NPM. Zod is available on [deno.land/x](https://deno.land/x). The latest version can be imported like so:
372
426
 
@@ -428,6 +482,7 @@ z.number();
428
482
  z.bigint();
429
483
  z.boolean();
430
484
  z.date();
485
+ z.symbol();
431
486
 
432
487
  // empty types
433
488
  z.undefined();
@@ -449,8 +504,12 @@ z.never();
449
504
  ```ts
450
505
  const tuna = z.literal("tuna");
451
506
  const twelve = z.literal(12);
507
+ const twobig = z.literal(2n); // bigint literal
452
508
  const tru = z.literal(true);
453
509
 
510
+ const terrificSymbol = Symbol("terrific");
511
+ const terrific = z.literal(terrificSymbol);
512
+
454
513
  // retrieve literal value
455
514
  tuna.value; // "tuna"
456
515
  ```
@@ -472,18 +531,11 @@ z.string().cuid();
472
531
  z.string().regex(regex);
473
532
  z.string().startsWith(string);
474
533
  z.string().endsWith(string);
475
-
476
- // trim whitespace
477
- z.string().trim();
478
-
479
- // deprecated, equivalent to .min(1)
480
- z.string().nonempty();
481
-
482
- // optional custom error message
483
- z.string().nonempty({ message: "Can't be empty" });
534
+ z.string().trim(); // trim whitespace
535
+ z.string().datetime(); // defaults to UTC, see below for options
484
536
  ```
485
537
 
486
- > Check out [validator.js](https://github.com/validatorjs/validator.js) for a bunch of other useful string validation functions.
538
+ > 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).
487
539
 
488
540
  You can customize some common error messages when creating a string schema.
489
541
 
@@ -505,6 +557,67 @@ z.string().url({ message: "Invalid url" });
505
557
  z.string().uuid({ message: "Invalid UUID" });
506
558
  z.string().startsWith("https://", { message: "Must provide secure URL" });
507
559
  z.string().endsWith(".com", { message: "Only .com domains allowed" });
560
+ z.string().datetime({ message: "Invalid datetime string! Must be UTC." });
561
+ ```
562
+
563
+ ## Coercion for primitives
564
+
565
+ Zod now provides a more convenient way to coerce primitive values.
566
+
567
+ ```ts
568
+ const schema = z.coerce.string();
569
+ schema.parse("tuna"); // => "tuna"
570
+ schema.parse(12); // => "12"
571
+ schema.parse(true); // => "true"
572
+ ```
573
+
574
+ During the parsing step, the input is passed through the `String()` function, which is a JavaScript built-in for coercing data into strings. Note that the returned schema is a `ZodString` instance so you can use all string methods.
575
+
576
+ ```ts
577
+ z.coerce.string().email().min(5);
578
+ ```
579
+
580
+ All primitive types support coercion.
581
+
582
+ ```ts
583
+ z.coerce.string(); // String(input)
584
+ z.coerce.number(); // Number(input)
585
+ z.coerce.boolean(); // Boolean(input)
586
+ z.coerce.bigint(); // BigInt(input)
587
+ z.coerce.date(); // new Date(input)
588
+ ```
589
+
590
+ ### Datetime validation
591
+
592
+ The `z.string().datetime()` method defaults to UTC validation: no timezone offsets with arbitrary sub-second decimal precision.
593
+
594
+ ```ts
595
+ const datetime = z.string().datetime();
596
+
597
+ datetime.parse("2020-01-01T00:00:00Z"); // pass
598
+ datetime.parse("2020-01-01T00:00:00.123Z"); // pass
599
+ datetime.parse("2020-01-01T00:00:00.123456Z"); // pass (arbitrary precision)
600
+ datetime.parse("2020-01-01T00:00:00+02:00"); // fail (no offsets allowed)
601
+ ```
602
+
603
+ Timezone offsets can be allowed by setting the `offset` option to `true`.
604
+
605
+ ```ts
606
+ const datetime = z.string().datetime({ offset: true });
607
+
608
+ datetime.parse("2020-01-01T00:00:00+02:00"); // pass
609
+ datetime.parse("2020-01-01T00:00:00.123+02:00"); // pass (millis optional)
610
+ datetime.parse("2020-01-01T00:00:00Z"); // pass (Z still supported)
611
+ ```
612
+
613
+ You can additionally constrain the allowable `precision`. By default, arbitrary sub-second precision is supported (but optional).
614
+
615
+ ```ts
616
+ const datetime = z.string().datetime({ precision: 3 });
617
+
618
+ datetime.parse("2020-01-01T00:00:00.123Z"); // pass
619
+ datetime.parse("2020-01-01T00:00:00Z"); // fail
620
+ datetime.parse("2020-01-01T00:00:00.123456Z"); // fail
508
621
  ```
509
622
 
510
623
  ## Numbers
@@ -534,6 +647,8 @@ z.number().negative(); // < 0
534
647
  z.number().nonpositive(); // <= 0
535
648
 
536
649
  z.number().multipleOf(5); // Evenly divisible by 5. Alias .step(5)
650
+
651
+ z.number().finite(); // value must be finite, not Infinity or -Infinity
537
652
  ```
538
653
 
539
654
  Optionally, you can pass in a second argument to provide a custom error message.
@@ -758,7 +873,7 @@ nullableString.parse(null); // => null
758
873
  Or use the `.nullable()` method.
759
874
 
760
875
  ```ts
761
- const E = z.string().nullable(); // equivalent to D
876
+ const E = z.string().nullable(); // equivalent to nullableString
762
877
  type E = z.infer<typeof E>; // string | null
763
878
  ```
764
879
 
@@ -927,6 +1042,41 @@ const deepPartialUser = user.deepPartial();
927
1042
 
928
1043
  > Important limitation: deep partials only work as expected in hierarchies of objects, arrays, and tuples.
929
1044
 
1045
+ ### `.required`
1046
+
1047
+ Contrary to the `.partial` method, the `.required` method makes all properties required.
1048
+
1049
+ Starting from this object:
1050
+
1051
+ ```ts
1052
+ const user = z.object({
1053
+ email: z.string()
1054
+ username: z.string(),
1055
+ }).partial();
1056
+ // { email?: string | undefined; username?: string | undefined }
1057
+ ```
1058
+
1059
+ We can create a required version:
1060
+
1061
+ ```ts
1062
+ const requiredUser = user.required();
1063
+ // { email: string; username: string }
1064
+ ```
1065
+
1066
+ You can also specify which properties to make required:
1067
+
1068
+ ```ts
1069
+ const requiredEmail = user.required({
1070
+ email: true,
1071
+ });
1072
+ /*
1073
+ {
1074
+ email: string;
1075
+ username?: string | undefined;
1076
+ }
1077
+ */
1078
+ ```
1079
+
930
1080
  ### `.passthrough`
931
1081
 
932
1082
  By default Zod object schemas strip out unrecognized keys during parsing.
@@ -1103,21 +1253,25 @@ const stringOrNumber = z.string().or(z.number());
1103
1253
 
1104
1254
  ## Discriminated unions
1105
1255
 
1106
- If the union consists of object schemas all identifiable by a common property, it is possible to use
1107
- the `z.discriminatedUnion` method.
1256
+ A discriminated union is a union of object schemas that all share a particular key.
1257
+
1258
+ ```ts
1259
+ type MyUnion =
1260
+ | { status: "success"; data: string }
1261
+ | { status: "failed"; error: Error };
1262
+ ```
1263
+
1264
+ Such unions can be represented with the `z.discriminatedUnion` method. This enables faster evaluation, because Zod can check the _discriminator key_ (`status` in the example above) to determine which schema should be used to parse the input. This makes parsing more efficient and lets Zod report friendlier errors.
1108
1265
 
1109
- The advantage is in more efficient evaluation and more human friendly errors. With the basic union method the input is
1110
- tested against each of the provided "options", and in the case of invalidity, issues for all the "options" are shown in
1111
- the zod error. On the other hand, the discriminated union allows for selecting just one of the "options", testing
1112
- against it, and showing only the issues related to this "option".
1266
+ With the basic union method the input is tested against each of the provided "options", and in the case of invalidity, issues for all the "options" are shown in the zod error. On the other hand, the discriminated union allows for selecting just one of the "options", testing against it, and showing only the issues related to this "option".
1113
1267
 
1114
1268
  ```ts
1115
- const item = z
1116
- .discriminatedUnion("type", [
1117
- z.object({ type: z.literal("a"), a: z.string() }),
1118
- z.object({ type: z.literal("b"), b: z.string() }),
1119
- ])
1120
- .parse({ type: "a", a: "abc" });
1269
+ const myUnion = z.discriminatedUnion("status", [
1270
+ z.object({ status: z.literal("success"), data: z.string() }),
1271
+ z.object({ status: z.literal("failed"), error: z.instanceof(Error) }),
1272
+ ]);
1273
+
1274
+ myUnion.parse({ type: "success", data: "yippie ki yay" });
1121
1275
  ```
1122
1276
 
1123
1277
  ## Records
@@ -1815,6 +1969,37 @@ numberWithRandomDefault.parse(undefined); // => 0.1871840107401901
1815
1969
  numberWithRandomDefault.parse(undefined); // => 0.7223408162401552
1816
1970
  ```
1817
1971
 
1972
+ Conceptually, this is how Zod processes default values:
1973
+
1974
+ 1. If the input is `undefined`, the default value is returned
1975
+ 2. Otherwise, the data is parsed using the base schema
1976
+
1977
+ ### `.catch`
1978
+
1979
+ Use `.catch()` to provide a "catch value" to be returned in the event of a parsing error.
1980
+
1981
+ ```ts
1982
+ const numberWithCatch = z.number().catch(42);
1983
+
1984
+ numberWithCatch.parse(5); // => 5
1985
+ numberWithCatch.parse("tuna"); // => 42
1986
+ ```
1987
+
1988
+ Optionally, you can pass a function into `.catch` that will be re-executed whenever a default value needs to be generated:
1989
+
1990
+ ```ts
1991
+ const numberWithRandomCatch = z.number().catch(Math.random);
1992
+
1993
+ numberWithRandomDefault.parse("sup"); // => 0.4413456736055323
1994
+ numberWithRandomDefault.parse("sup"); // => 0.1871840107401901
1995
+ numberWithRandomDefault.parse("sup"); // => 0.7223408162401552
1996
+ ```
1997
+
1998
+ Conceptually, this is how Zod processes "catch values":
1999
+
2000
+ 1. The data is parsed using the base schema
2001
+ 2. If the parsing fails, the "catch value" is returned
2002
+
1818
2003
  ### `.optional`
1819
2004
 
1820
2005
  A convenience method that returns an optional version of a schema.
@@ -1910,7 +2095,7 @@ petCat(fido); // works fine
1910
2095
  In some cases, its can be desirable to simulate _nominal typing_ inside TypeScript. For instance, you may wish to write a function that only accepts an input that has been validated by Zod. This can be achieved with _branded types_ (AKA _opaque types_).
1911
2096
 
1912
2097
  ```ts
1913
- const Cat = z.object({ name: z.string }).brand<"Cat">();
2098
+ const Cat = z.object({ name: z.string() }).brand<"Cat">();
1914
2099
  type Cat = z.infer<typeof Cat>;
1915
2100
 
1916
2101
  const petCat = (cat: Cat) => {};
@@ -1926,7 +2111,7 @@ petCat({ name: "fido" });
1926
2111
  Under the hood, this works by attaching a "brand" to the inferred type using an intersection type. This way, plain/unbranded data structures are no longer assignable to the inferred type of the schema.
1927
2112
 
1928
2113
  ```ts
1929
- const Cat = z.object({ name: z.string }).brand<"Cat">();
2114
+ const Cat = z.object({ name: z.string() }).brand<"Cat">();
1930
2115
  type Cat = z.infer<typeof Cat>;
1931
2116
  // {name: string} & {[symbol]: "Cat"}
1932
2117
  ```
@@ -2051,6 +2236,8 @@ if (!data.success) {
2051
2236
 
2052
2237
  > 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)
2053
2238
 
2239
+ Zod's error reporting emphasizes _completeness_ and _correctness_. If you are looking to present a useful error message to the end user, you should either override Zod's error messages using an error map (described in detail in the Error Handling guide) or use a third party library like [`zod-validation-error`](https://github.com/causaly/zod-validation-error)
2240
+
2054
2241
  ### Error formatting
2055
2242
 
2056
2243
  You can use the `.format()` method to convert this error into a nested object.
@@ -0,0 +1,43 @@
1
+ export declare namespace env {
2
+ const browser: boolean;
3
+ const node: boolean;
4
+ }
5
+ export declare const root: boolean;
6
+ export declare const parser: string;
7
+ export declare const plugins: string[];
8
+ declare const _extends: string[];
9
+ export { _extends as extends };
10
+ export declare const rules: {
11
+ "import/order": number;
12
+ "import/no-unresolved": number;
13
+ "import/no-duplicates": number;
14
+ /**
15
+ * eslint-plugin-simple-import-sort @see https://github.com/lydell/eslint-plugin-simple-import-sort
16
+ */
17
+ "sort-imports": number;
18
+ "simple-import-sort/imports": number;
19
+ "simple-import-sort/exports": number;
20
+ /**
21
+ * @typescript-eslint/eslint-plugin @see https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin
22
+ */
23
+ "@typescript-eslint/no-namespace": string;
24
+ "@typescript-eslint/explicit-module-boundary-types": string;
25
+ "@typescript-eslint/no-explicit-any": string;
26
+ "@typescript-eslint/ban-types": string;
27
+ "@typescript-eslint/no-unused-vars": string;
28
+ "@typescript-eslint/no-empty-function": string;
29
+ "@typescript-eslint/ban-ts-comment": string;
30
+ "@typescript-eslint/no-non-null-assertion": string;
31
+ "@typescript-eslint/no-empty-interface": string;
32
+ /**
33
+ * ESLint core rules @see https://eslint.org/docs/rules/
34
+ */
35
+ "no-case-declarations": string;
36
+ "no-empty": string;
37
+ "no-useless-escape": string;
38
+ "no-control-regex": string;
39
+ "ban/ban": (number | {
40
+ name: string[];
41
+ message: string;
42
+ })[];
43
+ };
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ module.exports = {
3
+ env: { browser: true, node: true },
4
+ root: true,
5
+ parser: "@typescript-eslint/parser",
6
+ plugins: [
7
+ "@typescript-eslint",
8
+ "import",
9
+ "simple-import-sort",
10
+ "unused-imports",
11
+ "ban",
12
+ ],
13
+ extends: [
14
+ "eslint:recommended",
15
+ "plugin:@typescript-eslint/recommended",
16
+ "prettier",
17
+ ],
18
+ rules: {
19
+ "import/order": 0,
20
+ "import/no-unresolved": 0,
21
+ "import/no-duplicates": 1,
22
+ /**
23
+ * eslint-plugin-simple-import-sort @see https://github.com/lydell/eslint-plugin-simple-import-sort
24
+ */
25
+ "sort-imports": 0,
26
+ "simple-import-sort/imports": 1,
27
+ "simple-import-sort/exports": 1,
28
+ /**
29
+ * @typescript-eslint/eslint-plugin @see https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/eslint-plugin
30
+ */
31
+ "@typescript-eslint/no-namespace": "off",
32
+ "@typescript-eslint/explicit-module-boundary-types": "off",
33
+ "@typescript-eslint/no-explicit-any": "off",
34
+ "@typescript-eslint/ban-types": "off",
35
+ "@typescript-eslint/no-unused-vars": "off",
36
+ "@typescript-eslint/no-empty-function": "off",
37
+ "@typescript-eslint/ban-ts-comment": "off",
38
+ "@typescript-eslint/no-non-null-assertion": "off",
39
+ "@typescript-eslint/no-empty-interface": "off",
40
+ /**
41
+ * ESLint core rules @see https://eslint.org/docs/rules/
42
+ */
43
+ "no-case-declarations": "off",
44
+ "no-empty": "off",
45
+ "no-useless-escape": "off",
46
+ "no-control-regex": "off",
47
+ "ban/ban": [
48
+ 2,
49
+ {
50
+ name: ["Object", "keys"],
51
+ message: "Object.keys() is not supported in legacy browsers, use objectKeys()",
52
+ },
53
+ {
54
+ name: ["Object", "setPrototypeOf"],
55
+ message: "Object.setPrototypeOf() is not supported in legacy browsers",
56
+ },
57
+ {
58
+ name: ["Number", "isNaN"],
59
+ message: "Number.isNaN() is not supported in legacy browsers",
60
+ },
61
+ {
62
+ name: ["Number", "isInteger"],
63
+ message: "Number.isInteger() is not supported in legacy browsers",
64
+ },
65
+ ],
66
+ },
67
+ };