zod 3.17.8 → 3.18.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
@@ -47,7 +47,7 @@
47
47
  - [Sponsors](#sponsors)
48
48
  - [Ecosystem](#ecosystem)
49
49
  - [Installation](#installation)
50
- - [Node/npm](#Node/npm)
50
+ - [Node/npm](#nodenpm)
51
51
  - [Deno](#deno)
52
52
  - [Basic usage](#basic-usage)
53
53
  - [Primitives](#primitives)
@@ -63,6 +63,7 @@
63
63
  - [Nullables](#nullables)
64
64
  - [Objects](#objects)
65
65
  - [.shape](#shape)
66
+ - [.enum](#enum)
66
67
  - [.extend](#extend)
67
68
  - [.merge](#merge)
68
69
  - [.pick/.omit](#pickomit)
@@ -89,6 +90,7 @@
89
90
  - [Instanceof](#instanceof)
90
91
  - [Function schemas](#function-schemas)
91
92
  - [Preprocess](#preprocess)
93
+ - [Branded types](#branded-types)
92
94
  - [Schema methods](#schema-methods)
93
95
  - [.parse](#parse)
94
96
  - [.parseAsync](#parseasync)
@@ -226,7 +228,7 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
226
228
  <a href="https://seasoned.cc">seasoned.cc</a>
227
229
  </td>
228
230
  <td align="center">
229
- <a href="https://seasoned.cc">
231
+ <a href="https://interval.com">
230
232
  <img src="https://avatars.githubusercontent.com/u/67802063?s=200&v=4" width="150px;" alt="" />
231
233
  </a>
232
234
  <br />
@@ -283,6 +285,17 @@ Sponsorship at any level is appreciated and encouraged. For individual developer
283
285
  <a href="https://adaptable.io/">adaptable.io</a>
284
286
  <br />
285
287
  </td>
288
+ <td align="center">
289
+ <a href="https://www.avanawallet.com/">
290
+ <img src="https://avatars.githubusercontent.com/u/105452197?s=200&v=4" width="100px;" alt="Avana Wallet logo"/>
291
+ </a>
292
+ <br />
293
+ <b>Avana Wallet</b>
294
+ <br/>
295
+ <a href="https://www.avanawallet.com/">avanawallet.com</a><br/>
296
+ <span>Solana non-custodial wallet</span>
297
+ <br />
298
+ </td>
286
299
  </tr>
287
300
  </table>
288
301
 
@@ -315,6 +328,8 @@ There are a growing number of tools that are built atop or support Zod natively!
315
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.
316
329
  - [`zod-xlsx`](https://github.com/sidwebworks/zod-xlsx): A xlsx based resource validator using Zod schemas.
317
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.
318
333
 
319
334
  #### Form integrations
320
335
 
@@ -557,7 +572,7 @@ z.date().safeParse(new Date()); // success: true
557
572
  z.date().safeParse("2022-01-12T00:00:00.000Z"); // success: false
558
573
  ```
559
574
 
560
- You can customize certain error messages when creating a boolean schema.
575
+ You can customize certain error messages when creating a date schema.
561
576
 
562
577
  ```ts
563
578
  const myDateSchema = z.date({
@@ -575,7 +590,7 @@ z.date().max(new Date(), { message: "Too young!" });
575
590
 
576
591
  **Supporting date strings**
577
592
 
578
- To write a schema that accepts either a `Date` or a date string, use (`z.preprocess`)[#preprocess].
593
+ To write a schema that accepts either a `Date` or a date string, use [`z.preprocess`](#preprocess).
579
594
 
580
595
  ```ts
581
596
  const dateSchema = z.preprocess((arg) => {
@@ -782,6 +797,15 @@ Dog.shape.name; // => string schema
782
797
  Dog.shape.age; // => number schema
783
798
  ```
784
799
 
800
+ ### `.keyof`
801
+
802
+ Use `.key` to create a `ZodEnum` schema from the keys of an object schema.
803
+
804
+ ```ts
805
+ const keySchema = Dog.keyof();
806
+ keySchema; // ZodEnum<["name", "age"]>
807
+ ```
808
+
785
809
  ### `.extend`
786
810
 
787
811
  You can add additional fields to an object schema with the `.extend` method.
@@ -1442,7 +1466,7 @@ All Zod schemas contain certain methods.
1442
1466
 
1443
1467
  ### `.parse`
1444
1468
 
1445
- `.parse(data:unknown): T`
1469
+ `.parse(data: unknown): T`
1446
1470
 
1447
1471
  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.
1448
1472
 
@@ -1694,7 +1718,7 @@ const Strings = z
1694
1718
  To transform data after parsing, use the `transform` method.
1695
1719
 
1696
1720
  ```ts
1697
- const stringToNumber = z.string().transform((val) => myString.length);
1721
+ const stringToNumber = z.string().transform((val) => val.length);
1698
1722
  stringToNumber.parse("string"); // => 6
1699
1723
  ```
1700
1724
 
@@ -1790,7 +1814,7 @@ z.optional(z.string());
1790
1814
 
1791
1815
  ### `.nullable`
1792
1816
 
1793
- A convenience method that returns an nullable version of a schema.
1817
+ A convenience method that returns a nullable version of a schema.
1794
1818
 
1795
1819
  ```ts
1796
1820
  const nullableString = z.string().nullable(); // string | null
@@ -1854,6 +1878,47 @@ z.object({ name: z.string() }).and(z.object({ age: z.number() })); // { name: st
1854
1878
  z.intersection(z.object({ name: z.string() }), z.object({ age: z.number() }));
1855
1879
  ```
1856
1880
 
1881
+ ### `.brand`
1882
+
1883
+ `.brand<T>() => ZodBranded<this, B>`
1884
+
1885
+ TypeScript's type system is structural, which means that any two types that are structurally equivalent are considered the same.
1886
+
1887
+ ```ts
1888
+ type Cat = { name: string };
1889
+ type Dog = { name: string };
1890
+
1891
+ const petCat = (cat: Cat) => {};
1892
+ const fido: Dog = { name: "fido" };
1893
+ petCat(fido); // works fine
1894
+ ```
1895
+
1896
+ 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_).
1897
+
1898
+ ```ts
1899
+ const Cat = z.object({ name: z.string }).brand<"Cat">();
1900
+ type Cat = z.infer<typeof Cat>;
1901
+
1902
+ const petCat = (cat: Cat) => {};
1903
+
1904
+ // this works
1905
+ const simba = Cat.parse({ name: "simba" });
1906
+ petCat(simba);
1907
+
1908
+ // this doesn't
1909
+ petCat({ name: "fido" });
1910
+ ```
1911
+
1912
+ 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.
1913
+
1914
+ ```ts
1915
+ const Cat = z.object({ name: z.string }).brand<"Cat">();
1916
+ type Cat = z.infer<typeof Cat>;
1917
+ // {name: string} & {[symbol]: "Cat"}
1918
+ ```
1919
+
1920
+ Note that branded types do not affect the runtime result of `.parse`. It is a static-only construct.
1921
+
1857
1922
  ## Guides and concepts
1858
1923
 
1859
1924
  ### Type inference
package/lib/ZodError.js CHANGED
@@ -171,7 +171,7 @@ const defaultErrorMap = (issue, _ctx) => {
171
171
  message = `Invalid input: must start with "${issue.validation.startsWith}"`;
172
172
  }
173
173
  else if ("endsWith" in issue.validation) {
174
- message = `Invalid input: must start with "${issue.validation.endsWith}"`;
174
+ message = `Invalid input: must end with "${issue.validation.endsWith}"`;
175
175
  }
176
176
  else {
177
177
  util_1.util.assertNever(issue.validation);
@@ -0,0 +1,8 @@
1
+ export declare namespace enumUtil {
2
+ type UnionToIntersectionFn<T> = (T extends unknown ? (k: () => T) => void : never) extends (k: infer Intersection) => void ? Intersection : never;
3
+ type GetUnionLast<T> = UnionToIntersectionFn<T> extends () => infer Last ? Last : never;
4
+ type UnionToTuple<T, Tuple extends unknown[] = []> = [T] extends [never] ? Tuple : UnionToTuple<Exclude<T, GetUnionLast<T>>, [GetUnionLast<T>, ...Tuple]>;
5
+ type CastToStringTuple<T> = T extends [string, ...string[]] ? T : never;
6
+ export type UnionToTupleString<T> = CastToStringTuple<UnionToTuple<T>>;
7
+ export {};
8
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,22 +1,24 @@
1
1
  export declare namespace util {
2
- type AssertEqual<T, Expected> = [T] extends [Expected] ? [Expected] extends [T] ? true : false : false;
3
- function assertEqual<A, B>(_cond: AssertEqual<A, B>): void;
4
- function assertNever(_x: never): never;
5
- type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
6
- type OmitKeys<T, K extends string> = Pick<T, Exclude<keyof T, K>>;
7
- type MakePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
8
- const arrayToEnum: <T extends string, U extends [T, ...T[]]>(items: U) => { [k in U[number]]: k; };
9
- const getValidEnumValues: (obj: any) => any[];
10
- const objectValues: (obj: any) => any[];
11
- const objectKeys: ObjectConstructor["keys"];
12
- const find: <T>(arr: T[], checker: (arg: T) => any) => T | undefined;
13
- type identity<T> = T;
14
- type flatten<T extends object> = identity<{
2
+ type AssertEqual<T, U> = (<V>() => V extends T ? 1 : 2) extends <V>() => V extends U ? 1 : 2 ? true : false;
3
+ export const assertEqual: <A, B>(val: AssertEqual<A, B>) => AssertEqual<A, B>;
4
+ export function assertIs<T>(_arg: T): void;
5
+ export function assertNever(_x: never): never;
6
+ export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
7
+ export type OmitKeys<T, K extends string> = Pick<T, Exclude<keyof T, K>>;
8
+ export type MakePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
9
+ export const arrayToEnum: <T extends string, U extends [T, ...T[]]>(items: U) => { [k in U[number]]: k; };
10
+ export const getValidEnumValues: (obj: any) => any[];
11
+ export const objectValues: (obj: any) => any[];
12
+ export const objectKeys: ObjectConstructor["keys"];
13
+ export const find: <T>(arr: T[], checker: (arg: T) => any) => T | undefined;
14
+ export type identity<T> = T;
15
+ export type flatten<T> = identity<{
15
16
  [k in keyof T]: T[k];
16
17
  }>;
17
- type noUndefined<T> = T extends undefined ? never : T;
18
- const isInteger: NumberConstructor["isInteger"];
19
- function joinValues<T extends any[]>(array: T, separator?: string): string;
18
+ export type noUndefined<T> = T extends undefined ? never : T;
19
+ export const isInteger: NumberConstructor["isInteger"];
20
+ export function joinValues<T extends any[]>(array: T, separator?: string): string;
21
+ export {};
20
22
  }
21
23
  export declare const ZodParsedType: {
22
24
  function: "function";
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getParsedType = exports.ZodParsedType = exports.util = void 0;
4
4
  var util;
5
5
  (function (util) {
6
- function assertEqual(_cond) { }
7
- util.assertEqual = assertEqual;
6
+ util.assertEqual = (val) => val;
7
+ function assertIs(_arg) { }
8
+ util.assertIs = assertIs;
8
9
  function assertNever(_x) {
9
10
  throw new Error();
10
11
  }
package/lib/index.mjs CHANGED
@@ -1,7 +1,8 @@
1
1
  var util;
2
2
  (function (util) {
3
- function assertEqual(_cond) { }
4
- util.assertEqual = assertEqual;
3
+ util.assertEqual = (val) => val;
4
+ function assertIs(_arg) { }
5
+ util.assertIs = assertIs;
5
6
  function assertNever(_x) {
6
7
  throw new Error();
7
8
  }
@@ -285,7 +286,7 @@ const defaultErrorMap = (issue, _ctx) => {
285
286
  message = `Invalid input: must start with "${issue.validation.startsWith}"`;
286
287
  }
287
288
  else if ("endsWith" in issue.validation) {
288
- message = `Invalid input: must start with "${issue.validation.endsWith}"`;
289
+ message = `Invalid input: must end with "${issue.validation.endsWith}"`;
289
290
  }
290
291
  else {
291
292
  util.assertNever(issue.validation);
@@ -490,11 +491,10 @@ function processCreateParams(params) {
490
491
  const customMap = (iss, ctx) => {
491
492
  if (iss.code !== "invalid_type")
492
493
  return { message: ctx.defaultError };
493
- if (typeof ctx.data === "undefined" && required_error)
494
- return { message: required_error };
495
- if (params.invalid_type_error)
496
- return { message: params.invalid_type_error };
497
- return { message: ctx.defaultError };
494
+ if (typeof ctx.data === "undefined") {
495
+ return { message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError };
496
+ }
497
+ return { message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError };
498
498
  };
499
499
  return { errorMap: customMap, description };
500
500
  }
@@ -707,6 +707,13 @@ class ZodType {
707
707
  typeName: ZodFirstPartyTypeKind.ZodDefault,
708
708
  });
709
709
  }
710
+ brand() {
711
+ return new ZodBranded({
712
+ typeName: ZodFirstPartyTypeKind.ZodBranded,
713
+ type: this,
714
+ ...processCreateParams(undefined),
715
+ });
716
+ }
710
717
  describe(description) {
711
718
  const This = this.constructor;
712
719
  return new This({
@@ -1805,6 +1812,9 @@ class ZodObject extends ZodType {
1805
1812
  shape: () => newShape,
1806
1813
  });
1807
1814
  }
1815
+ keyof() {
1816
+ return createZodEnum(util.objectKeys(this.shape));
1817
+ }
1808
1818
  }
1809
1819
  ZodObject.create = (shape, params) => {
1810
1820
  return new ZodObject({
@@ -2870,6 +2880,21 @@ ZodNaN.create = (params) => {
2870
2880
  ...processCreateParams(params),
2871
2881
  });
2872
2882
  };
2883
+ const BRAND = Symbol("zod_brand");
2884
+ class ZodBranded extends ZodType {
2885
+ _parse(input) {
2886
+ const { ctx } = this._processInputParams(input);
2887
+ const data = ctx.data;
2888
+ return this._def.type._parse({
2889
+ data,
2890
+ path: ctx.path,
2891
+ parent: ctx,
2892
+ });
2893
+ }
2894
+ unwrap() {
2895
+ return this._def.type;
2896
+ }
2897
+ }
2873
2898
  const custom = (check, params = {}, fatal) => {
2874
2899
  if (check)
2875
2900
  return ZodAny.create().superRefine((data, ctx) => {
@@ -2917,6 +2942,7 @@ var ZodFirstPartyTypeKind;
2917
2942
  ZodFirstPartyTypeKind["ZodNullable"] = "ZodNullable";
2918
2943
  ZodFirstPartyTypeKind["ZodDefault"] = "ZodDefault";
2919
2944
  ZodFirstPartyTypeKind["ZodPromise"] = "ZodPromise";
2945
+ ZodFirstPartyTypeKind["ZodBranded"] = "ZodBranded";
2920
2946
  })(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
2921
2947
  const instanceOfType = (cls, params = {
2922
2948
  message: `Input not instance of ${cls.name}`,
@@ -3007,6 +3033,8 @@ var mod = /*#__PURE__*/Object.freeze({
3007
3033
  ZodNullable: ZodNullable,
3008
3034
  ZodDefault: ZodDefault,
3009
3035
  ZodNaN: ZodNaN,
3036
+ BRAND: BRAND,
3037
+ ZodBranded: ZodBranded,
3010
3038
  custom: custom,
3011
3039
  Schema: ZodType,
3012
3040
  ZodSchema: ZodType,
@@ -3057,4 +3085,4 @@ var mod = /*#__PURE__*/Object.freeze({
3057
3085
  getErrorMap: getErrorMap
3058
3086
  });
3059
3087
 
3060
- export { DIRTY, EMPTY_PATH, INVALID, OK, ParseStatus, ZodType as Schema, ZodAny, ZodArray, ZodBigInt, ZodBoolean, ZodDate, ZodDefault, ZodDiscriminatedUnion, ZodEffects, ZodEnum, ZodError, ZodFirstPartyTypeKind, ZodFunction, ZodIntersection, ZodIssueCode, ZodLazy, ZodLiteral, ZodMap, ZodNaN, ZodNativeEnum, ZodNever, ZodNull, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodParsedType, ZodPromise, ZodRecord, ZodType as ZodSchema, ZodSet, ZodString, ZodEffects as ZodTransformer, ZodTuple, ZodType, ZodUndefined, ZodUnion, ZodUnknown, ZodVoid, addIssueToContext, anyType as any, arrayType as array, bigIntType as bigint, booleanType as boolean, custom, dateType as date, mod as default, defaultErrorMap, discriminatedUnionType as discriminatedUnion, effectsType as effect, enumType as enum, functionType as function, getErrorMap, getParsedType, instanceOfType as instanceof, intersectionType as intersection, isAborted, isAsync, isDirty, isValid, jsonStringifyReplacer, late, lazyType as lazy, literalType as literal, makeIssue, mapType as map, nanType as nan, nativeEnumType as nativeEnum, neverType as never, nullType as null, nullableType as nullable, numberType as number, objectType as object, objectUtil, oboolean, onumber, optionalType as optional, ostring, preprocessType as preprocess, promiseType as promise, quotelessJson, recordType as record, setType as set, setErrorMap, strictObjectType as strictObject, stringType as string, effectsType as transformer, tupleType as tuple, undefinedType as undefined, unionType as union, unknownType as unknown, voidType as void, mod as z };
3088
+ export { BRAND, DIRTY, EMPTY_PATH, INVALID, OK, ParseStatus, ZodType as Schema, ZodAny, ZodArray, ZodBigInt, ZodBoolean, ZodBranded, ZodDate, ZodDefault, ZodDiscriminatedUnion, ZodEffects, ZodEnum, ZodError, ZodFirstPartyTypeKind, ZodFunction, ZodIntersection, ZodIssueCode, ZodLazy, ZodLiteral, ZodMap, ZodNaN, ZodNativeEnum, ZodNever, ZodNull, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodParsedType, ZodPromise, ZodRecord, ZodType as ZodSchema, ZodSet, ZodString, ZodEffects as ZodTransformer, ZodTuple, ZodType, ZodUndefined, ZodUnion, ZodUnknown, ZodVoid, addIssueToContext, anyType as any, arrayType as array, bigIntType as bigint, booleanType as boolean, custom, dateType as date, mod as default, defaultErrorMap, discriminatedUnionType as discriminatedUnion, effectsType as effect, enumType as enum, functionType as function, getErrorMap, getParsedType, instanceOfType as instanceof, intersectionType as intersection, isAborted, isAsync, isDirty, isValid, jsonStringifyReplacer, late, lazyType as lazy, literalType as literal, makeIssue, mapType as map, nanType as nan, nativeEnumType as nativeEnum, neverType as never, nullType as null, nullableType as nullable, numberType as number, objectType as object, objectUtil, oboolean, onumber, optionalType as optional, ostring, preprocessType as preprocess, promiseType as promise, quotelessJson, recordType as record, setType as set, setErrorMap, strictObjectType as strictObject, stringType as string, effectsType as transformer, tupleType as tuple, undefinedType as undefined, unionType as union, unknownType as unknown, voidType as void, mod as z };
package/lib/index.umd.js CHANGED
@@ -6,8 +6,9 @@
6
6
 
7
7
  var util;
8
8
  (function (util) {
9
- function assertEqual(_cond) { }
10
- util.assertEqual = assertEqual;
9
+ util.assertEqual = (val) => val;
10
+ function assertIs(_arg) { }
11
+ util.assertIs = assertIs;
11
12
  function assertNever(_x) {
12
13
  throw new Error();
13
14
  }
@@ -291,7 +292,7 @@
291
292
  message = `Invalid input: must start with "${issue.validation.startsWith}"`;
292
293
  }
293
294
  else if ("endsWith" in issue.validation) {
294
- message = `Invalid input: must start with "${issue.validation.endsWith}"`;
295
+ message = `Invalid input: must end with "${issue.validation.endsWith}"`;
295
296
  }
296
297
  else {
297
298
  util.assertNever(issue.validation);
@@ -496,11 +497,10 @@
496
497
  const customMap = (iss, ctx) => {
497
498
  if (iss.code !== "invalid_type")
498
499
  return { message: ctx.defaultError };
499
- if (typeof ctx.data === "undefined" && required_error)
500
- return { message: required_error };
501
- if (params.invalid_type_error)
502
- return { message: params.invalid_type_error };
503
- return { message: ctx.defaultError };
500
+ if (typeof ctx.data === "undefined") {
501
+ return { message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError };
502
+ }
503
+ return { message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError };
504
504
  };
505
505
  return { errorMap: customMap, description };
506
506
  }
@@ -713,6 +713,13 @@
713
713
  typeName: exports.ZodFirstPartyTypeKind.ZodDefault,
714
714
  });
715
715
  }
716
+ brand() {
717
+ return new ZodBranded({
718
+ typeName: exports.ZodFirstPartyTypeKind.ZodBranded,
719
+ type: this,
720
+ ...processCreateParams(undefined),
721
+ });
722
+ }
716
723
  describe(description) {
717
724
  const This = this.constructor;
718
725
  return new This({
@@ -1811,6 +1818,9 @@
1811
1818
  shape: () => newShape,
1812
1819
  });
1813
1820
  }
1821
+ keyof() {
1822
+ return createZodEnum(util.objectKeys(this.shape));
1823
+ }
1814
1824
  }
1815
1825
  ZodObject.create = (shape, params) => {
1816
1826
  return new ZodObject({
@@ -2876,6 +2886,21 @@
2876
2886
  ...processCreateParams(params),
2877
2887
  });
2878
2888
  };
2889
+ const BRAND = Symbol("zod_brand");
2890
+ class ZodBranded extends ZodType {
2891
+ _parse(input) {
2892
+ const { ctx } = this._processInputParams(input);
2893
+ const data = ctx.data;
2894
+ return this._def.type._parse({
2895
+ data,
2896
+ path: ctx.path,
2897
+ parent: ctx,
2898
+ });
2899
+ }
2900
+ unwrap() {
2901
+ return this._def.type;
2902
+ }
2903
+ }
2879
2904
  const custom = (check, params = {}, fatal) => {
2880
2905
  if (check)
2881
2906
  return ZodAny.create().superRefine((data, ctx) => {
@@ -2923,6 +2948,7 @@
2923
2948
  ZodFirstPartyTypeKind["ZodNullable"] = "ZodNullable";
2924
2949
  ZodFirstPartyTypeKind["ZodDefault"] = "ZodDefault";
2925
2950
  ZodFirstPartyTypeKind["ZodPromise"] = "ZodPromise";
2951
+ ZodFirstPartyTypeKind["ZodBranded"] = "ZodBranded";
2926
2952
  })(exports.ZodFirstPartyTypeKind || (exports.ZodFirstPartyTypeKind = {}));
2927
2953
  const instanceOfType = (cls, params = {
2928
2954
  message: `Input not instance of ${cls.name}`,
@@ -3013,6 +3039,8 @@
3013
3039
  ZodNullable: ZodNullable,
3014
3040
  ZodDefault: ZodDefault,
3015
3041
  ZodNaN: ZodNaN,
3042
+ BRAND: BRAND,
3043
+ ZodBranded: ZodBranded,
3016
3044
  custom: custom,
3017
3045
  Schema: ZodType,
3018
3046
  ZodSchema: ZodType,
@@ -3063,6 +3091,7 @@
3063
3091
  getErrorMap: getErrorMap
3064
3092
  });
3065
3093
 
3094
+ exports.BRAND = BRAND;
3066
3095
  exports.DIRTY = DIRTY;
3067
3096
  exports.EMPTY_PATH = EMPTY_PATH;
3068
3097
  exports.INVALID = INVALID;
@@ -3073,6 +3102,7 @@
3073
3102
  exports.ZodArray = ZodArray;
3074
3103
  exports.ZodBigInt = ZodBigInt;
3075
3104
  exports.ZodBoolean = ZodBoolean;
3105
+ exports.ZodBranded = ZodBranded;
3076
3106
  exports.ZodDate = ZodDate;
3077
3107
  exports.ZodDefault = ZodDefault;
3078
3108
  exports.ZodDiscriminatedUnion = ZodDiscriminatedUnion;
package/lib/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { enumUtil } from "./helpers/enumUtil";
1
2
  import { errorUtil } from "./helpers/errorUtil";
2
3
  import { AsyncParseReturnType, ParseContext, ParseInput, ParseParams, ParseReturnType, ParseStatus, SyncParseReturnType } from "./helpers/parseUtil";
3
4
  import { partialUtil } from "./helpers/partialUtil";
@@ -74,6 +75,7 @@ export declare abstract class ZodType<Output = any, Def extends ZodTypeDef = Zod
74
75
  transform<NewOut>(transform: (arg: Output, ctx: RefinementCtx) => NewOut | Promise<NewOut>): ZodEffects<this, NewOut>;
75
76
  default(def: util.noUndefined<Input>): ZodDefault<this>;
76
77
  default(def: () => util.noUndefined<Input>): ZodDefault<this>;
78
+ brand<B extends string | number | symbol>(): ZodBranded<this, B>;
77
79
  describe(description: string): this;
78
80
  isOptional(): boolean;
79
81
  isNullable(): boolean;
@@ -352,9 +354,6 @@ export declare type objectInputType<Shape extends ZodRawShape, Catchall extends
352
354
  declare type deoptional<T extends ZodTypeAny> = T extends ZodOptional<infer U> ? deoptional<U> : T;
353
355
  export declare type SomeZodObject = ZodObject<ZodRawShape, UnknownKeysParam, ZodTypeAny, any, any>;
354
356
  export declare class ZodObject<T extends ZodRawShape, UnknownKeys extends UnknownKeysParam = "strip", Catchall extends ZodTypeAny = ZodTypeAny, Output = objectOutputType<T, Catchall>, Input = objectInputType<T, Catchall>> extends ZodType<Output, ZodObjectDef<T, UnknownKeys, Catchall>, Input> {
355
- readonly _shape: T;
356
- readonly _unknownKeys: UnknownKeys;
357
- readonly _catchall: Catchall;
358
357
  private _cached;
359
358
  _getCached(): {
360
359
  shape: T;
@@ -380,7 +379,7 @@ export declare class ZodObject<T extends ZodRawShape, UnknownKeys extends Unknow
380
379
  * inferred type of merged objects. Please
381
380
  * upgrade if you are experiencing issues.
382
381
  */
383
- merge<Incoming extends AnyZodObject>(merging: Incoming): ZodObject<extendShape<T, Incoming["_shape"]>, UnknownKeys, Catchall>;
382
+ merge<Incoming extends AnyZodObject>(merging: Incoming): ZodObject<extendShape<T, ReturnType<Incoming["_def"]["shape"]>>, UnknownKeys, Catchall>;
384
383
  catchall<Index extends ZodTypeAny>(index: Index): ZodObject<T, UnknownKeys, Index>;
385
384
  pick<Mask extends {
386
385
  [k in keyof T]?: true;
@@ -400,6 +399,7 @@ export declare class ZodObject<T extends ZodRawShape, UnknownKeys extends Unknow
400
399
  required(): ZodObject<{
401
400
  [k in keyof T]: deoptional<T[k]>;
402
401
  }, UnknownKeys, Catchall>;
402
+ keyof(): ZodEnum<enumUtil.UnionToTupleString<keyof T>>;
403
403
  static create: <T_1 extends ZodRawShape>(shape: T_1, params?: RawCreateParams) => ZodObject<T_1, "strip", ZodTypeAny, { [k_1 in keyof objectUtil.addQuestionMarks<{ [k in keyof T_1]: T_1[k]["_output"]; }>]: objectUtil.addQuestionMarks<{ [k in keyof T_1]: T_1[k]["_output"]; }>[k_1]; }, { [k_3 in keyof objectUtil.addQuestionMarks<{ [k_2 in keyof T_1]: T_1[k_2]["_input"]; }>]: objectUtil.addQuestionMarks<{ [k_2 in keyof T_1]: T_1[k_2]["_input"]; }>[k_3]; }>;
404
404
  static strictCreate: <T_1 extends ZodRawShape>(shape: T_1, params?: RawCreateParams) => ZodObject<T_1, "strict", ZodTypeAny, { [k_1 in keyof objectUtil.addQuestionMarks<{ [k in keyof T_1]: T_1[k]["_output"]; }>]: objectUtil.addQuestionMarks<{ [k in keyof T_1]: T_1[k]["_output"]; }>[k_1]; }, { [k_3 in keyof objectUtil.addQuestionMarks<{ [k_2 in keyof T_1]: T_1[k_2]["_input"]; }>]: objectUtil.addQuestionMarks<{ [k_2 in keyof T_1]: T_1[k_2]["_input"]; }>[k_3]; }>;
405
405
  static lazycreate: <T_1 extends ZodRawShape>(shape: () => T_1, params?: RawCreateParams) => ZodObject<T_1, "strip", ZodTypeAny, { [k_1 in keyof objectUtil.addQuestionMarks<{ [k in keyof T_1]: T_1[k]["_output"]; }>]: objectUtil.addQuestionMarks<{ [k in keyof T_1]: T_1[k]["_output"]; }>[k_1]; }, { [k_3 in keyof objectUtil.addQuestionMarks<{ [k_2 in keyof T_1]: T_1[k_2]["_input"]; }>]: objectUtil.addQuestionMarks<{ [k_2 in keyof T_1]: T_1[k_2]["_input"]; }>[k_3]; }>;
@@ -474,7 +474,7 @@ export declare class ZodTuple<T extends [ZodTypeAny, ...ZodTypeAny[]] | [] = [Zo
474
474
  _parse(input: ParseInput): ParseReturnType<this["_output"]>;
475
475
  get items(): T;
476
476
  rest<Rest extends ZodTypeAny>(rest: Rest): ZodTuple<T, Rest>;
477
- static create: <T_1 extends [ZodTypeAny, ...ZodTypeAny[]] | []>(schemas: T_1, params?: RawCreateParams) => ZodTuple<T_1, null>;
477
+ static create: <T_1 extends [] | [ZodTypeAny, ...ZodTypeAny[]]>(schemas: T_1, params?: RawCreateParams) => ZodTuple<T_1, null>;
478
478
  }
479
479
  export interface ZodRecordDef<Key extends KeySchema = ZodString, Value extends ZodTypeAny = ZodTypeAny> extends ZodTypeDef {
480
480
  valueType: Value;
@@ -664,6 +664,20 @@ export declare class ZodNaN extends ZodType<number, ZodNaNDef> {
664
664
  _parse(input: ParseInput): ParseReturnType<any>;
665
665
  static create: (params?: RawCreateParams) => ZodNaN;
666
666
  }
667
+ export interface ZodBrandedDef<T extends ZodTypeAny> extends ZodTypeDef {
668
+ type: T;
669
+ typeName: ZodFirstPartyTypeKind.ZodBranded;
670
+ }
671
+ export declare const BRAND: unique symbol;
672
+ export declare type BRAND<T extends string | number | symbol> = {
673
+ [BRAND]: {
674
+ [k in T]: true;
675
+ };
676
+ };
677
+ export declare class ZodBranded<T extends ZodTypeAny, B extends string | number | symbol> extends ZodType<T["_output"] & BRAND<B>, ZodBrandedDef<T>, T["_input"] & BRAND<B>> {
678
+ _parse(input: ParseInput): ParseReturnType<any>;
679
+ unwrap(): T;
680
+ }
667
681
  export declare const custom: <T>(check?: ((data: unknown) => any) | undefined, params?: Parameters<ZodTypeAny["refine"]>[1], fatal?: boolean | undefined) => ZodType<T, ZodTypeDef, T>;
668
682
  export { ZodType as Schema, ZodType as ZodSchema };
669
683
  export declare const late: {
@@ -700,9 +714,10 @@ export declare enum ZodFirstPartyTypeKind {
700
714
  ZodOptional = "ZodOptional",
701
715
  ZodNullable = "ZodNullable",
702
716
  ZodDefault = "ZodDefault",
703
- ZodPromise = "ZodPromise"
717
+ ZodPromise = "ZodPromise",
718
+ ZodBranded = "ZodBranded"
704
719
  }
705
- export declare type ZodFirstPartySchemaTypes = ZodString | ZodNumber | ZodNaN | ZodBigInt | ZodBoolean | ZodDate | ZodUndefined | ZodNull | ZodAny | ZodUnknown | ZodNever | ZodVoid | ZodArray<any, any> | ZodObject<any, any, any, any, any> | ZodUnion<any> | ZodDiscriminatedUnion<any, any, any> | ZodIntersection<any, any> | ZodTuple<any, any> | ZodRecord<any, any> | ZodMap<any> | ZodSet<any> | ZodFunction<any, any> | ZodLazy<any> | ZodLiteral<any> | ZodEnum<any> | ZodEffects<any, any, any> | ZodNativeEnum<any> | ZodOptional<any> | ZodNullable<any> | ZodDefault<any> | ZodPromise<any>;
720
+ export declare type ZodFirstPartySchemaTypes = ZodString | ZodNumber | ZodNaN | ZodBigInt | ZodBoolean | ZodDate | ZodUndefined | ZodNull | ZodAny | ZodUnknown | ZodNever | ZodVoid | ZodArray<any, any> | ZodObject<any, any, any, any, any> | ZodUnion<any> | ZodDiscriminatedUnion<any, any, any> | ZodIntersection<any, any> | ZodTuple<any, any> | ZodRecord<any, any> | ZodMap<any> | ZodSet<any> | ZodFunction<any, any> | ZodLazy<any> | ZodLiteral<any> | ZodEnum<any> | ZodEffects<any, any, any> | ZodNativeEnum<any> | ZodOptional<any> | ZodNullable<any> | ZodDefault<any> | ZodPromise<any> | ZodBranded<any, any>;
706
721
  declare const instanceOfType: <T extends new (...args: any[]) => any>(cls: T, params?: Parameters<ZodTypeAny["refine"]>[1]) => ZodType<InstanceType<T>, ZodTypeDef, InstanceType<T>>;
707
722
  declare const stringType: (params?: RawCreateParams) => ZodString;
708
723
  declare const numberType: (params?: RawCreateParams) => ZodNumber;
@@ -722,7 +737,7 @@ declare const strictObjectType: <T extends ZodRawShape>(shape: T, params?: RawCr
722
737
  declare const unionType: <T extends readonly [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]>(types: T, params?: RawCreateParams) => ZodUnion<T>;
723
738
  declare const discriminatedUnionType: typeof ZodDiscriminatedUnion.create;
724
739
  declare const intersectionType: <T extends ZodTypeAny, U extends ZodTypeAny>(left: T, right: U, params?: RawCreateParams) => ZodIntersection<T, U>;
725
- declare const tupleType: <T extends [ZodTypeAny, ...ZodTypeAny[]] | []>(schemas: T, params?: RawCreateParams) => ZodTuple<T, null>;
740
+ declare const tupleType: <T extends [] | [ZodTypeAny, ...ZodTypeAny[]]>(schemas: T, params?: RawCreateParams) => ZodTuple<T, null>;
726
741
  declare const recordType: typeof ZodRecord.create;
727
742
  declare const mapType: <Key extends ZodTypeAny = ZodTypeAny, Value extends ZodTypeAny = ZodTypeAny>(keyType: Key, valueType: Value, params?: RawCreateParams) => ZodMap<Key, Value>;
728
743
  declare const setType: <Value extends ZodTypeAny = ZodTypeAny>(valueType: Value, params?: RawCreateParams) => ZodSet<Value>;
package/lib/types.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = exports.discriminatedUnion = exports.date = exports.boolean = exports.bigint = exports.array = exports.any = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodNaN = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.objectUtil = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.ZodType = void 0;
4
- exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = void 0;
3
+ exports.function = exports.enum = exports.effect = exports.discriminatedUnion = exports.date = exports.boolean = exports.bigint = exports.array = exports.any = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.objectUtil = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.ZodType = void 0;
4
+ exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = void 0;
5
5
  const errorUtil_1 = require("./helpers/errorUtil");
6
6
  const parseUtil_1 = require("./helpers/parseUtil");
7
7
  const util_1 = require("./helpers/util");
@@ -41,11 +41,10 @@ function processCreateParams(params) {
41
41
  const customMap = (iss, ctx) => {
42
42
  if (iss.code !== "invalid_type")
43
43
  return { message: ctx.defaultError };
44
- if (typeof ctx.data === "undefined" && required_error)
45
- return { message: required_error };
46
- if (params.invalid_type_error)
47
- return { message: params.invalid_type_error };
48
- return { message: ctx.defaultError };
44
+ if (typeof ctx.data === "undefined") {
45
+ return { message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError };
46
+ }
47
+ return { message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError };
49
48
  };
50
49
  return { errorMap: customMap, description };
51
50
  }
@@ -258,6 +257,13 @@ class ZodType {
258
257
  typeName: ZodFirstPartyTypeKind.ZodDefault,
259
258
  });
260
259
  }
260
+ brand() {
261
+ return new ZodBranded({
262
+ typeName: ZodFirstPartyTypeKind.ZodBranded,
263
+ type: this,
264
+ ...processCreateParams(undefined),
265
+ });
266
+ }
261
267
  describe(description) {
262
268
  const This = this.constructor;
263
269
  return new This({
@@ -1372,6 +1378,9 @@ class ZodObject extends ZodType {
1372
1378
  shape: () => newShape,
1373
1379
  });
1374
1380
  }
1381
+ keyof() {
1382
+ return createZodEnum(util_1.util.objectKeys(this.shape));
1383
+ }
1375
1384
  }
1376
1385
  exports.ZodObject = ZodObject;
1377
1386
  ZodObject.create = (shape, params) => {
@@ -2457,6 +2466,22 @@ ZodNaN.create = (params) => {
2457
2466
  ...processCreateParams(params),
2458
2467
  });
2459
2468
  };
2469
+ exports.BRAND = Symbol("zod_brand");
2470
+ class ZodBranded extends ZodType {
2471
+ _parse(input) {
2472
+ const { ctx } = this._processInputParams(input);
2473
+ const data = ctx.data;
2474
+ return this._def.type._parse({
2475
+ data,
2476
+ path: ctx.path,
2477
+ parent: ctx,
2478
+ });
2479
+ }
2480
+ unwrap() {
2481
+ return this._def.type;
2482
+ }
2483
+ }
2484
+ exports.ZodBranded = ZodBranded;
2460
2485
  const custom = (check, params = {}, fatal) => {
2461
2486
  if (check)
2462
2487
  return ZodAny.create().superRefine((data, ctx) => {
@@ -2505,6 +2530,7 @@ var ZodFirstPartyTypeKind;
2505
2530
  ZodFirstPartyTypeKind["ZodNullable"] = "ZodNullable";
2506
2531
  ZodFirstPartyTypeKind["ZodDefault"] = "ZodDefault";
2507
2532
  ZodFirstPartyTypeKind["ZodPromise"] = "ZodPromise";
2533
+ ZodFirstPartyTypeKind["ZodBranded"] = "ZodBranded";
2508
2534
  })(ZodFirstPartyTypeKind = exports.ZodFirstPartyTypeKind || (exports.ZodFirstPartyTypeKind = {}));
2509
2535
  const instanceOfType = (cls, params = {
2510
2536
  message: `Input not instance of ${cls.name}`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.17.8",
3
+ "version": "3.18.0",
4
4
  "description": "TypeScript-first schema declaration and validation library with static type inference",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./index.d.ts",
@@ -59,7 +59,7 @@
59
59
  "test": "jest --coverage",
60
60
  "test:deno": "cd deno && deno test",
61
61
  "prepublishOnly": "npm run test && npm run build && npm run build:deno",
62
- "play": "nodemon -e ts -w . -x esr src/playground.ts",
62
+ "play": "nodemon -e ts -w . -x tsx src/playground.ts",
63
63
  "depcruise": "depcruise -c .dependency-cruiser.js src",
64
64
  "benchmark": "esr src/benchmarks/index.ts",
65
65
  "prepare": "husky install"
@@ -73,8 +73,6 @@
73
73
  "@typescript-eslint/parser": "^5.15.0",
74
74
  "benchmark": "^2.1.4",
75
75
  "dependency-cruiser": "^9.19.0",
76
- "esbuild": "^0.14.49",
77
- "esbuild-runner": "^2.2.1",
78
76
  "eslint": "^8.11.0",
79
77
  "eslint-config-prettier": "^8.5.0",
80
78
  "eslint-plugin-ban": "^1.6.0",
@@ -91,6 +89,7 @@
91
89
  "ts-jest": "^27.1.3",
92
90
  "ts-morph": "^14.0.0",
93
91
  "tslib": "^2.3.1",
92
+ "tsx": "^3.8.0",
94
93
  "typescript": "4.1"
95
94
  },
96
95
  "lint-staged": {