zod 3.8.2 → 3.9.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
@@ -29,6 +29,12 @@
29
29
  - [Literals](#literals)
30
30
  - [Strings](#strings)
31
31
  - [Numbers](#numbers)
32
+ - [Booleans](#booleans)
33
+ - [Enums](#enums)
34
+ - [Zod enums](#zod-enums)
35
+ - [Native enums](#native-enums)
36
+ - [Optionals](#optionals)
37
+ - [Nullables](#nullables)
32
38
  - [Objects](#objects)
33
39
  - [.shape](#shape)
34
40
  - [.extend](#extend)
@@ -40,19 +46,14 @@
40
46
  - [.strict](#strict)
41
47
  - [.strip](#strip)
42
48
  - [.catchall](#catchall)
43
- - [Records](#records)
44
- - [Maps](#maps)
45
- - [Sets](#sets)
46
49
  - [Arrays](#arrays)
47
50
  - [.nonempty](#nonempty)
48
51
  - [.min/.max/.length](#minmaxlength)
49
- - [Unions](#unions)
50
- - [Optionals](#optionals)
51
- - [Nullables](#nullables)
52
- - [Enums](#enums)
53
- - [Zod enums](#zod-enums)
54
- - [Native enums](#native-enums)
55
52
  - [Tuples](#tuples)
53
+ - [Records](#records)
54
+ - [Maps](#maps)
55
+ - [Sets](#sets)
56
+ - [Unions](#unions)
56
57
  - [Recursive types](#recursive-types)
57
58
  - [JSON type](#json-type)
58
59
  - [Cyclical data](#cyclical-objects)
@@ -60,7 +61,7 @@
60
61
  - [Instanceof](#instanceof)
61
62
  - [Function schemas](#function-schemas)
62
63
  - [Preprocess](#preprocess)
63
- - [Base class methods (ZodType)](#zodtype-methods-and-properties)
64
+ - [Schema methods](#zodtype-methods-and-properties)
64
65
  - [.parse](#parse)
65
66
  - [.parseAsync](#parseasync)
66
67
  - [.safeParse](#safeparse)
@@ -229,8 +230,14 @@ import { z } from "zod";
229
230
 
230
231
  // creating a schema for strings
231
232
  const mySchema = z.string();
233
+
234
+ // parsing
232
235
  mySchema.parse("tuna"); // => "tuna"
233
236
  mySchema.parse(12); // => throws ZodError
237
+
238
+ // "safe" parsing (doesn't throw error if validation fails)
239
+ mySchema.safeParse("tuna"); // => { success: true; data: "tuna" }
240
+ mySchema.safeParse(12); // => { success: false; error: ZodError }
234
241
  ```
235
242
 
236
243
  Creating an object schema
@@ -242,7 +249,7 @@ const User = z.object({
242
249
  username: z.string(),
243
250
  });
244
251
 
245
- User.parse({ username: string });
252
+ User.parse({ username: "Ludwig" });
246
253
 
247
254
  // extract the inferred type
248
255
  type User = z.infer<typeof User>;
@@ -293,6 +300,15 @@ tuna.value; // "tuna"
293
300
 
294
301
  ## Strings
295
302
 
303
+ You can customize certain errors when creating a string schema.
304
+
305
+ ```ts
306
+ const name = z.string({
307
+ required: "Name is required",
308
+ invalid: "Invalid name",
309
+ });
310
+ ```
311
+
296
312
  Zod includes a handful of string-specific validations.
297
313
 
298
314
  ```ts
@@ -316,19 +332,37 @@ z.string().nonempty({ message: "Can't be empty" });
316
332
 
317
333
  #### Custom error messages
318
334
 
319
- Optionally, you can pass in a second argument to provide a custom error message.
335
+ You can customize certain errors when creating a string schema.
336
+
337
+ ```ts
338
+ const name = z.string({
339
+ required_error: "Name is required",
340
+ invalid_type_error: "Name must be a string",
341
+ });
342
+ ```
343
+
344
+ When using validation methods, you can pass in an additional argument to provide a custom error message.
320
345
 
321
346
  ```ts
322
347
  z.string().min(5, { message: "Must be 5 or more characters long" });
323
348
  z.string().max(5, { message: "Must be 5 or fewer characters long" });
324
349
  z.string().length(5, { message: "Must be exactly 5 characters long" });
325
- z.string().email({ message: "Invalid email address." });
350
+ z.string().email({ message: "Invalid email address" });
326
351
  z.string().url({ message: "Invalid url" });
327
352
  z.string().uuid({ message: "Invalid UUID" });
328
353
  ```
329
354
 
330
355
  ## Numbers
331
356
 
357
+ You can customize certain error messages when creating a number schema.
358
+
359
+ ```ts
360
+ const age = z.number({
361
+ required_error: "Age is required",
362
+ invalid_type_error: "Age must be a number",
363
+ });
364
+ ```
365
+
332
366
  Zod includes a handful of number-specific validations.
333
367
 
334
368
  ```ts
@@ -343,6 +377,8 @@ z.number().positive(); // > 0
343
377
  z.number().nonnegative(); // >= 0
344
378
  z.number().negative(); // < 0
345
379
  z.number().nonpositive(); // <= 0
380
+
381
+ z.number().multipleOf(5); // Evenly divisible by 5. Alias .step(5)
346
382
  ```
347
383
 
348
384
  Optionally, you can pass in a second argument to provide a custom error message.
@@ -351,6 +387,183 @@ Optionally, you can pass in a second argument to provide a custom error message.
351
387
  z.number().lte(5, { message: "this👏is👏too👏big" });
352
388
  ```
353
389
 
390
+ ## Booleans
391
+
392
+ You can customize certain error messages when creating a boolean schema.
393
+
394
+ ```ts
395
+ const isActive = z.boolean({
396
+ required_error: "isActive is required",
397
+ invalid_type_error: "isActive must be a boolean",
398
+ });
399
+ ```
400
+
401
+ ## Enums
402
+
403
+ There are two ways to define enums in Zod.
404
+
405
+ ### Zod enums
406
+
407
+ ```ts
408
+ const FishEnum = z.enum(["Salmon", "Tuna", "Trout"]);
409
+ type FishEnum = z.infer<typeof FishEnum>;
410
+ // 'Salmon' | 'Tuna' | 'Trout'
411
+ ```
412
+
413
+ You must 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.
414
+
415
+ ```ts
416
+ const VALUES = ["Salmon", "Tuna", "Trout"] as const;
417
+ const FishEnum = z.enum(VALUES);
418
+ ```
419
+
420
+ This is not allowed:
421
+
422
+ ```ts
423
+ const fish = ["Salmon", "Tuna", "Trout"];
424
+ const FishEnum = z.enum(fish);
425
+ ```
426
+
427
+ In that case, the inferred type of `fish` is simply `string[]`, so Zod isn't able to infer the individual enum elements.
428
+
429
+ **Autocompletion**
430
+
431
+ To get autocompletion with a Zod enum, use the `.enum` property of your schema:
432
+
433
+ ```ts
434
+ FishEnum.enum.Salmon; // => autocompletes
435
+
436
+ FishEnum.enum;
437
+ /*
438
+ => {
439
+ Salmon: "Salmon",
440
+ Tuna: "Tuna",
441
+ Trout: "Trout",
442
+ }
443
+ */
444
+ ```
445
+
446
+ You can also retrieve the list of options as a tuple with the `.options` property:
447
+
448
+ ```ts
449
+ FishEnum.options; // ["Salmon", "Tuna", "Trout"]);
450
+ ```
451
+
452
+ ### Native enums
453
+
454
+ 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()` .
455
+
456
+ **Numeric enums**
457
+
458
+ ```ts
459
+ enum Fruits {
460
+ Apple,
461
+ Banana,
462
+ }
463
+
464
+ const FruitEnum = z.nativeEnum(Fruits);
465
+ type FruitEnum = z.infer<typeof FruitEnum>; // Fruits
466
+
467
+ FruitEnum.parse(Fruits.Apple); // passes
468
+ FruitEnum.parse(Fruits.Banana); // passes
469
+ FruitEnum.parse(0); // passes
470
+ FruitEnum.parse(1); // passes
471
+ FruitEnum.parse(3); // fails
472
+ ```
473
+
474
+ **String enums**
475
+
476
+ ```ts
477
+ enum Fruits {
478
+ Apple = "apple",
479
+ Banana = "banana",
480
+ Cantaloupe, // you can mix numerical and string enums
481
+ }
482
+
483
+ const FruitEnum = z.nativeEnum(Fruits);
484
+ type FruitEnum = z.infer<typeof FruitEnum>; // Fruits
485
+
486
+ FruitEnum.parse(Fruits.Apple); // passes
487
+ FruitEnum.parse(Fruits.Cantaloupe); // passes
488
+ FruitEnum.parse("apple"); // passes
489
+ FruitEnum.parse("banana"); // passes
490
+ FruitEnum.parse(0); // passes
491
+ FruitEnum.parse("Cantaloupe"); // fails
492
+ ```
493
+
494
+ **Const enums**
495
+
496
+ The `.nativeEnum()` function works for `as const` objects as well. ⚠️ `as const` required TypeScript 3.4+!
497
+
498
+ ```ts
499
+ const Fruits = {
500
+ Apple: "apple",
501
+ Banana: "banana",
502
+ Cantaloupe: 3,
503
+ } as const;
504
+
505
+ const FruitEnum = z.nativeEnum(Fruits);
506
+ type FruitEnum = z.infer<typeof FruitEnum>; // "apple" | "banana" | 3
507
+
508
+ FruitEnum.parse("apple"); // passes
509
+ FruitEnum.parse("banana"); // passes
510
+ FruitEnum.parse(3); // passes
511
+ FruitEnum.parse("Cantaloupe"); // fails
512
+ ```
513
+
514
+ ## Optionals
515
+
516
+ You can make any schema optional with `z.optional()`:
517
+
518
+ ```ts
519
+ const schema = z.optional(z.string());
520
+
521
+ schema.parse(undefined); // => returns undefined
522
+ type A = z.infer<typeof A>; // string | undefined
523
+ ```
524
+
525
+ You can make an existing schema optional with the `.optional()` method:
526
+
527
+ ```ts
528
+ const user = z.object({
529
+ username: z.string().optional(),
530
+ });
531
+ type C = z.infer<typeof C>; // { username?: string | undefined };
532
+ ```
533
+
534
+ #### `.unwrap`
535
+
536
+ ```ts
537
+ const stringSchema = z.string();
538
+ const optionalString = stringSchema.optional();
539
+ optionalString.unwrap() === stringSchema; // true
540
+ ```
541
+
542
+ ## Nullables
543
+
544
+ Similarly, you can create nullable types like so:
545
+
546
+ ```ts
547
+ const nullableString = z.nullable(z.string());
548
+ nullableString.parse("asdf"); // => "asdf"
549
+ nullableString.parse(null); // => null
550
+ ```
551
+
552
+ You can make an existing schema nullable with the `nullable` method:
553
+
554
+ ```ts
555
+ const E = z.string().nullable(); // equivalent to D
556
+ type E = z.infer<typeof D>; // string | null
557
+ ```
558
+
559
+ #### `.unwrap`
560
+
561
+ ```ts
562
+ const stringSchema = z.string();
563
+ const nullableString = stringSchema.nullable();
564
+ nullableString.unwrap() === stringSchema; // true
565
+ ```
566
+
354
567
  ## Objects
355
568
 
356
569
  ```ts
@@ -442,16 +655,31 @@ Starting from this object:
442
655
 
443
656
  ```ts
444
657
  const user = z.object({
658
+ email: z.string()
445
659
  username: z.string(),
446
660
  });
447
- // { username: string }
661
+ // { email: string; username: string }
448
662
  ```
449
663
 
450
664
  We can create a partial version:
451
665
 
452
666
  ```ts
453
667
  const partialUser = user.partial();
454
- // { username?: string | undefined }
668
+ // { email?: string | undefined; username?: string | undefined }
669
+ ```
670
+
671
+ You can also specify which properties to make optional:
672
+
673
+ ```ts
674
+ const optionalEmail = user.partial({
675
+ email: true,
676
+ });
677
+ /*
678
+ {
679
+ email?: string | undefined;
680
+ username: string
681
+ }
682
+ */
455
683
  ```
456
684
 
457
685
  ### `.deepPartial`
@@ -608,6 +836,23 @@ z.string().array().length(5); // must contain 5 items exactly
608
836
 
609
837
  Unlike `.nonempty()` these methods do not change the inferred type.
610
838
 
839
+ ## Tuples
840
+
841
+ Unlike arrays, tuples have a fixed number of elements and each element can have a different type.
842
+
843
+ ```ts
844
+ const athleteSchema = z.tuple([
845
+ z.string(), // name
846
+ z.number(), // jersey number
847
+ z.object({
848
+ pointsScored: z.number(),
849
+ }), // statistics
850
+ ]);
851
+
852
+ type Athlete = z.infer<typeof athleteSchema>;
853
+ // type Athlete = [string, number, { pointsScored: number }]
854
+ ```
855
+
611
856
  ## Unions
612
857
 
613
858
  Zod includes a built-in `z.union` method for composing "OR" types.
@@ -627,79 +872,6 @@ For convenience, you can also use the `.or` method:
627
872
  const stringOrNumber = z.string().or(z.number());
628
873
  ```
629
874
 
630
- ## Optionals
631
-
632
- You can make any schema optional with `z.optional()`:
633
-
634
- ```ts
635
- const schema = z.optional(z.string());
636
-
637
- schema.parse(undefined); // => returns undefined
638
- type A = z.infer<typeof A>; // string | undefined
639
- ```
640
-
641
- You can make an existing schema optional with the `.optional()` method:
642
-
643
- ```ts
644
- const user = z.object({
645
- username: z.string().optional(),
646
- });
647
- type C = z.infer<typeof C>; // { username?: string | undefined };
648
- ```
649
-
650
- #### `.unwrap`
651
-
652
- ```ts
653
- const stringSchema = z.string();
654
- const optionalString = stringSchema.optional();
655
- optionalString.unwrap() === stringSchema; // true
656
- ```
657
-
658
- ## Nullables
659
-
660
- Similarly, you can create nullable types like so:
661
-
662
- ```ts
663
- const nullableString = z.nullable(z.string());
664
- nullableString.parse("asdf"); // => "asdf"
665
- nullableString.parse(null); // => null
666
- ```
667
-
668
- You can make an existing schema nullable with the `nullable` method:
669
-
670
- ```ts
671
- const E = z.string().nullable(); // equivalent to D
672
- type E = z.infer<typeof D>; // string | null
673
- ```
674
-
675
- #### `.unwrap`
676
-
677
- ```ts
678
- const stringSchema = z.string();
679
- const nullableString = stringSchema.nullable();
680
- nullableString.unwrap() === stringSchema; // true
681
- ```
682
-
683
- <!--
684
-
685
- ``` ts
686
- /* Custom Union Types */
687
-
688
- const F = z
689
- .union([z.string(), z.number(), z.boolean()])
690
- .optional()
691
- .nullable();
692
-
693
- F.parse('tuna'); // => tuna
694
- F.parse(42); // => 42
695
- F.parse(true); // => true
696
- F.parse(undefined); // => undefined
697
- F.parse(null); // => null
698
- F.parse({}); // => throws Error!
699
-
700
- type F = z.infer<typeof F>; // string | number | boolean | undefined | null;
701
- ``` -->
702
-
703
875
  ## Records
704
876
 
705
877
  Record schemas are used to validate types such as `{ [k: string]: number }`.
@@ -765,134 +937,6 @@ type numberSet = z.infer<typeof numberSet>;
765
937
  // Set<number>
766
938
  ```
767
939
 
768
- ## Enums
769
-
770
- There are two ways to define enums in Zod.
771
-
772
- ### Zod enums
773
-
774
- <!-- An enum is just a union of string literals, so you _could_ define an enum like this:
775
-
776
- ```ts
777
- const FishEnum = z.union([
778
- z.literal("Salmon"),
779
- z.literal("Tuna"),
780
- z.literal("Trout"),
781
- ]);
782
-
783
- FishEnum.parse("Salmon"); // => "Salmon"
784
- FishEnum.parse("Flounder"); // => throws
785
- ```
786
-
787
- For convenience Zod provides a built-in `z.enum()` function. Here's is the equivalent code: -->
788
-
789
- ```ts
790
- const FishEnum = z.enum(["Salmon", "Tuna", "Trout"]);
791
- type FishEnum = z.infer<typeof FishEnum>;
792
- // 'Salmon' | 'Tuna' | 'Trout'
793
- ```
794
-
795
- You must 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.
796
-
797
- ```ts
798
- const VALUES = ["Salmon", "Tuna", "Trout"] as const;
799
- const FishEnum = z.enum(VALUES);
800
- ```
801
-
802
- This is not allowed:
803
-
804
- ```ts
805
- const fish = ["Salmon", "Tuna", "Trout"];
806
- const FishEnum = z.enum(fish);
807
- ```
808
-
809
- In that case, the inferred type of `fish` is simply `string[]`, so Zod isn't able to infer the individual enum elements.
810
-
811
- **Autocompletion**
812
-
813
- To get autocompletion with a Zod enum, use the `.enum` property of your schema:
814
-
815
- ```ts
816
- FishEnum.enum.Salmon; // => autocompletes
817
-
818
- FishEnum.enum;
819
- /*
820
- => {
821
- Salmon: "Salmon",
822
- Tuna: "Tuna",
823
- Trout: "Trout",
824
- }
825
- */
826
- ```
827
-
828
- You can also retrieve the list of options as a tuple with the `.options` property:
829
-
830
- ```ts
831
- FishEnum.options; // ["Salmon", "Tuna", "Trout"]);
832
- ```
833
-
834
- ### Native enums
835
-
836
- 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()` .
837
-
838
- **Numeric enums**
839
-
840
- ```ts
841
- enum Fruits {
842
- Apple,
843
- Banana,
844
- }
845
-
846
- const FruitEnum = z.nativeEnum(Fruits);
847
- type FruitEnum = z.infer<typeof FruitEnum>; // Fruits
848
-
849
- FruitEnum.parse(Fruits.Apple); // passes
850
- FruitEnum.parse(Fruits.Banana); // passes
851
- FruitEnum.parse(0); // passes
852
- FruitEnum.parse(1); // passes
853
- FruitEnum.parse(3); // fails
854
- ```
855
-
856
- **String enums**
857
-
858
- ```ts
859
- enum Fruits {
860
- Apple = "apple",
861
- Banana = "banana",
862
- Cantaloupe, // you can mix numerical and string enums
863
- }
864
-
865
- const FruitEnum = z.nativeEnum(Fruits);
866
- type FruitEnum = z.infer<typeof FruitEnum>; // Fruits
867
-
868
- FruitEnum.parse(Fruits.Apple); // passes
869
- FruitEnum.parse(Fruits.Cantaloupe); // passes
870
- FruitEnum.parse("apple"); // passes
871
- FruitEnum.parse("banana"); // passes
872
- FruitEnum.parse(0); // passes
873
- FruitEnum.parse("Cantaloupe"); // fails
874
- ```
875
-
876
- **Const enums**
877
-
878
- The `.nativeEnum()` function works for `as const` objects as well. ⚠️ `as const` required TypeScript 3.4+!
879
-
880
- ```ts
881
- const Fruits = {
882
- Apple: "apple",
883
- Banana: "banana",
884
- Cantaloupe: 3,
885
- } as const;
886
-
887
- const FruitEnum = z.nativeEnum(Fruits);
888
- type FruitEnum = z.infer<typeof FruitEnum>; // "apple" | "banana" | 3
889
-
890
- FruitEnum.parse("apple"); // passes
891
- FruitEnum.parse("banana"); // passes
892
- FruitEnum.parse(3); // passes
893
- FruitEnum.parse("Cantaloupe"); // fails
894
- ```
895
-
896
940
  ## Intersections
897
941
 
898
942
  <!-- > ⚠️ Intersections are deprecated. If you are trying to merge objects, use the `.merge` method instead. -->
@@ -943,23 +987,6 @@ type Teacher = z.infer<typeof Teacher>;
943
987
  // { id:string; name:string };
944
988
  ``` -->
945
989
 
946
- ## Tuples
947
-
948
- Unlike arrays, tuples have a fixed number of elements and each element can have a different type.
949
-
950
- ```ts
951
- const athleteSchema = z.tuple([
952
- z.string(), // name
953
- z.number(), // jersey number
954
- z.object({
955
- pointsScored: z.number(),
956
- }), // statistics
957
- ]);
958
-
959
- type Athlete = z.infer<typeof athleteSchema>;
960
- // type Athlete = [string, number, { pointsScored: number }]
961
- ```
962
-
963
990
  ## Recursive types
964
991
 
965
992
  You can define a recursive schema in Zod, but because of a limitation of TypeScript, their type can't be statically inferred. Instead you'll need to define the type definition manually, and provide it to Zod as a "type hint".
@@ -1167,9 +1194,9 @@ myFunction; // (arg: string)=>number[]
1167
1194
 
1168
1195
  ## Preprocess
1169
1196
 
1170
- Typically Zod operates under a "parse, then tranform" 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).)
1197
+ 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).)
1171
1198
 
1172
- But sometimes you want to apply some transformation to the input _before_ parsing happens. A common use case: type coercion. Zod enables this with the `z.preprocess()`.
1199
+ But sometimes you want to apply some transform to the input _before_ parsing happens. A common use case: type coercion. Zod enables this with the `z.preprocess()`.
1173
1200
 
1174
1201
  ```ts
1175
1202
  const castToString = z.preprocess((val) => String(val), z.string());
@@ -1410,11 +1437,11 @@ const stringToNumber = z.string().transform((val) => myString.length);
1410
1437
  stringToNumber.parse("string"); // => 6
1411
1438
  ```
1412
1439
 
1413
- > ⚠️ Transformation functions must not throw. Make sure to use refinements before the transformer to make sure the input can be parsed by the transformer.
1440
+ > ⚠️ Transform functions must not throw. Make sure to use refinements before the transform to make sure the input can be parsed by the transform.
1414
1441
 
1415
1442
  #### Chaining order
1416
1443
 
1417
- Note that `stringToNumber` above is an instance of the `ZodEffects` subclass. It is NOT an instance of `ZodString`. If you want to use the built-in methods of `ZodString` (e.g. `.email()`) you must apply those methods _before_ any transformations.
1444
+ Note that `stringToNumber` above is an instance of the `ZodEffects` subclass. It is NOT an instance of `ZodString`. If you want to use the built-in methods of `ZodString` (e.g. `.email()`) you must apply those methods _before_ any transforms.
1418
1445
 
1419
1446
  ```ts
1420
1447
  const emailToDomain = z
@@ -1435,25 +1462,24 @@ z.string()
1435
1462
  .refine((val) => val > 25);
1436
1463
  ```
1437
1464
 
1438
- #### Async transformations
1465
+ #### Async transforms
1439
1466
 
1440
- Transformations can also be async.
1467
+ Transforms can also be async.
1441
1468
 
1442
1469
  ```ts
1443
- const IdToUser = z.transformer(
1444
- z.string().uuid(),
1445
- UserSchema,
1446
- (userId) => async (id) => {
1470
+ const IdToUser = z
1471
+ .string()
1472
+ .uuid()
1473
+ .transform(async (id) => {
1447
1474
  return await getUserById(id);
1448
- }
1449
- );
1475
+ });
1450
1476
  ```
1451
1477
 
1452
- > ⚠️ If your schema contains asynchronous transformers, you must use .parseAsync() or .safeParseAsync() to parse data. Otherwise Zod will throw an error.
1478
+ > ⚠️ If your schema contains asynchronous transforms, you must use .parseAsync() or .safeParseAsync() to parse data. Otherwise Zod will throw an error.
1453
1479
 
1454
1480
  ### `.default`
1455
1481
 
1456
- You can use transformers to implement the concept of "default values" in Zod.
1482
+ You can use transforms to implement the concept of "default values" in Zod.
1457
1483
 
1458
1484
  ```ts
1459
1485
  const stringWithDefault = z.string().default("tuna");
@@ -1539,7 +1565,7 @@ z.union([z.string(), z.number()]);
1539
1565
 
1540
1566
  ### `.and`
1541
1567
 
1542
- A convenience method for creating interesection types.
1568
+ A convenience method for creating intersection types.
1543
1569
 
1544
1570
  ```ts
1545
1571
  z.object({ name: z.string() }).and(z.object({ age: z.number() })); // { name: string } & { age: number }
@@ -1562,7 +1588,7 @@ const u: A = "asdf"; // compiles
1562
1588
 
1563
1589
  #### What about transforms?
1564
1590
 
1565
- In reality each Zod schema is actually associated with **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`.
1591
+ 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`.
1566
1592
 
1567
1593
  You can separately extract the input and output types like so:
1568
1594
 
@@ -1648,7 +1674,7 @@ Tuples
1648
1674
  Recursive Types
1649
1675
  Function Schemas
1650
1676
 
1651
- <abbr title="For instance, Yup allows custmo error messages with the syntax yup.number().min(5, 'Number must be more than 5!')">Validation Messages</abbr>
1677
+ <abbr title="For instance, Yup allows custom error messages with the syntax yup.number().min(5, 'Number must be more than 5!')">Validation Messages</abbr>
1652
1678
  Immutable instances
1653
1679
  Type Guards
1654
1680
  Validity Checking
@@ -1681,7 +1707,7 @@ Yup is a full-featured library that was implemented first in vanilla JS, and lat
1681
1707
 
1682
1708
  Differences
1683
1709
 
1684
- - Supports for casting and transformation
1710
+ - Supports casting and transforms
1685
1711
  - All object fields are optional by default
1686
1712
  - Missing object methods: (partial, deepPartial)
1687
1713
  <!-- - Missing nonempty arrays with proper typing (`[T, ...T[]]`) -->