Repository: colinhacks/zod
Pull request #4296 (2025-04-30 18:52:59)

Add methods to number formats


Patch:
diff --git a/packages/mini/src/schemas.ts b/packages/mini/src/schemas.ts
index ad829375..368967b6 100644
--- a/packages/mini/src/schemas.ts
+++ b/packages/mini/src/schemas.ts
@@ -439,7 +439,7 @@ export const ZodMiniNumberFormat: core.$constructor<ZodMiniNumberFormat> = /*@__
   "ZodMiniNumberFormat",
   (inst, def) => {
     core.$ZodNumberFormat.init(inst, def);
-    ZodMiniType.init(inst, def);
+    ZodMiniNumber.init(inst, def);
   }
 );
 
diff --git a/packages/zod/src/schemas.ts b/packages/zod/src/schemas.ts
index 1811bfc9..4255cb4e 100644
--- a/packages/zod/src/schemas.ts
+++ b/packages/zod/src/schemas.ts
@@ -182,6 +182,56 @@ export interface _ZodString<Input = unknown> extends ZodType {
   minLength: number | null;
   maxLength: number | null;
 
+  // /** @deprecated Use `z.jsonString()` instead. */
+  // json(params?: string | core.$ZodCheckJSONStringParams): this;
+
+  // miscellaneous checks
+  regex(regex: RegExp, params?: string | core.$ZodCheckRegexParams): this;
+  includes(value: string, params?: { message?: string; position?: number }): this;
+  startsWith(value: string, params?: string | core.$ZodCheckStartsWithParams): this;
+  endsWith(value: string, params?: string | core.$ZodCheckEndsWithParams): this;
+  min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this;
+  max(maxLength: number, params?: string | core.$ZodCheckMaxLengthParams): this;
+  length(len: number, params?: string | core.$ZodCheckLengthEqualsParams): this;
+  nonempty(params?: string | core.$ZodCheckMinLengthParams): this;
+  lowercase(params?: string | core.$ZodCheckLowerCaseParams): this;
+  uppercase(params?: string | core.$ZodCheckUpperCaseParams): this;
+
+  // transforms
+  trim(): this;
+  normalize(form?: "NFC" | "NFD" | "NFKC" | "NFKD" | (string & {})): this;
+  toLowerCase(): this;
+  toUpperCase(): this;
+}
+
+export const _ZodString: core.$constructor<_ZodString> = /*@__PURE__*/ core.$constructor("_ZodString", (inst, def) => {
+  core.$ZodString.init(inst, def);
+  ZodType.init(inst, def);
+
+  inst.format = inst._zod.computed.format ?? null;
+  inst.minLength = inst._zod.computed.minimum ?? null;
+  inst.maxLength = inst._zod.computed.maximum ?? null;
+
+  // validations
+  inst.regex = (...args) => inst.check(checks.regex(...args));
+  inst.includes = (...args) => inst.check(checks.includes(...args));
+  inst.startsWith = (params) => inst.check(checks.startsWith(params));
+  inst.endsWith = (params) => inst.check(checks.endsWith(params));
+  inst.min = (...args) => inst.check(checks.minLength(...args));
+  inst.max = (...args) => inst.check(checks.maxLength(...args));
+  inst.length = (...args) => inst.check(checks.length(...args));
+  inst.nonempty = (...args) => inst.check(checks.minLength(1, ...args));
+  inst.lowercase = (params) => inst.check(checks.lowercase(params));
+  inst.uppercase = (params) => inst.check(checks.uppercase(params));
+
+  // transforms
+  inst.trim = () => inst.check(checks.trim());
+  inst.normalize = (...args) => inst.check(checks.normalize(...args));
+  inst.toLowerCase = () => inst.check(checks.toLowerCase());
+  inst.toUpperCase = () => inst.check(checks.toUpperCase());
+});
+
+export interface ZodString extends _ZodString<string> {
   // string format checks
   // email(): ZodString;
   // email(params?: string): ZodString;
@@ -254,37 +304,11 @@ export interface _ZodString<Input = unknown> extends ZodType {
   ): this;
   /** @deprecated Use `z.iso.duration()` instead. */
   duration(params?: string | core.$ZodCheckISODurationParams): this;
-
-  // /** @deprecated Use `z.jsonString()` instead. */
-  // json(params?: string | core.$ZodCheckJSONStringParams): this;
-
-  // miscellaneous checks
-  regex(regex: RegExp, params?: string | core.$ZodCheckRegexParams): this;
-  includes(value: string, params?: { message?: string; position?: number }): this;
-  startsWith(value: string, params?: string | core.$ZodCheckStartsWithParams): this;
-  endsWith(value: string, params?: string | core.$ZodCheckEndsWithParams): this;
-  min(minLength: number, params?: string | core.$ZodCheckMinLengthParams): this;
-  max(maxLength: number, params?: string | core.$ZodCheckMaxLengthParams): this;
-  length(len: number, params?: string | core.$ZodCheckLengthEqualsParams): this;
-  nonempty(params?: string | core.$ZodCheckMinLengthParams): this;
-  lowercase(params?: string | core.$ZodCheckLowerCaseParams): this;
-  uppercase(params?: string | core.$ZodCheckUpperCaseParams): this;
-
-  // transforms
-  trim(): this;
-  normalize(form?: "NFC" | "NFD" | "NFKC" | "NFKD" | (string & {})): this;
-  toLowerCase(): this;
-  toUpperCase(): this;
 }
 
-export interface ZodString extends _ZodString<string> {}
 export const ZodString: core.$constructor<ZodString> = /*@__PURE__*/ core.$constructor("ZodString", (inst, def) => {
   core.$ZodString.init(inst, def);
-  ZodType.init(inst, def);
-
-  inst.format = inst._zod.computed.format ?? null;
-  inst.minLength = inst._zod.computed.minimum ?? null;
-  inst.maxLength = inst._zod.computed.maximum ?? null;
+  _ZodString.init(inst, def);
 
   inst.email = (params) => inst.check(core._email(ZodEmail, params));
   inst.url = (params) => inst.check(core._url(ZodURL, params));
@@ -302,16 +326,8 @@ export const ZodString: core.$constructor<ZodString> = /*@__PURE__*/ core.$const
   inst.ulid = (params) => inst.check(core._ulid(ZodULID, params));
   inst.base64 = (params) => inst.check(core._base64(ZodBase64, params));
   inst.base64url = (params) => inst.check(core._base64url(ZodBase64URL, params));
-  // inst.jsonString = (params) => inst.check(core._jsonString(Zodinst,params));
-  // inst.json = (params) => inst.check(core._jsonString(Zodinst,params));
   inst.xid = (params) => inst.check(core._xid(ZodXID, params));
   inst.ksuid = (params) => inst.check(core._ksuid(ZodKSUID, params));
-  // inst.ip = (params) => {
-  //   const version = (params ?? {} as any)?.version;
-  //   if (version === "v4") return inst.check(core._ipv4(ZodIPv4, params));
-  //   if (version === "v6") return inst.check(core._ipv6(ZodIPv6, params as any));
-  //   return union([inst.ipv4(params), inst.ipv6(params as any)]);
-  // };
   inst.ipv4 = (params) => inst.check(core._ipv4(ZodIPv4, params));
   inst.ipv6 = (params) => inst.check(core._ipv6(ZodIPv6, params));
   inst.cidrv4 = (params) => inst.check(core._cidrv4(ZodCIDRv4, params));
@@ -323,24 +339,6 @@ export const ZodString: core.$constructor<ZodString> = /*@__PURE__*/ core.$const
   inst.date = (params) => inst.check(iso.date(params as any));
   inst.time = (params) => inst.check(iso.time(params as any));
   inst.duration = (params) => inst.check(iso.duration(params as any));
-
-  // validations
-  inst.regex = (...args) => inst.check(checks.regex(...args));
-  inst.includes = (...args) => inst.check(checks.includes(...args));
-  inst.startsWith = (params) => inst.check(checks.startsWith(params));
-  inst.endsWith = (params) => inst.check(checks.endsWith(params));
-  inst.min = (...args) => inst.check(checks.minLength(...args));
-  inst.max = (...args) => inst.check(checks.maxLength(...args));
-  inst.length = (...args) => inst.check(checks.length(...args));
-  inst.nonempty = (...args) => inst.check(checks.minLength(1, ...args));
-  inst.lowercase = (params) => inst.check(checks.lowercase(params));
-  inst.uppercase = (params) => inst.check(checks.uppercase(params));
-
-  // transforms
-  inst.trim = () => inst.check(checks.trim());
-  inst.normalize = (...args) => inst.check(checks.normalize(...args));
-  inst.toLowerCase = () => inst.check(checks.toLowerCase());
-  inst.toUpperCase = () => inst.check(checks.toUpperCase());
 });
 
 export function string(params?: string | core.$ZodStringParams): ZodString {
@@ -348,14 +346,14 @@ export function string(params?: string | core.$ZodStringParams): ZodString {
 }
 
 // ZodStringFormat
-export interface ZodStringFormat<Format extends core.$ZodStringFormats = core.$ZodStringFormats> extends ZodString {
+export interface ZodStringFormat<Format extends core.$ZodStringFormats = core.$ZodStringFormats> extends _ZodString {
   _zod: core.$ZodStringFormatInternals<Format>;
 }
 export const ZodStringFormat: core.$constructor<ZodStringFormat> = /*@__PURE__*/ core.$constructor(
   "ZodStringFormat",
   (inst, def) => {
     core.$ZodStringFormat.init(inst, def);
-    ZodString.init(inst, def);
+    _ZodString.init(inst, def);
   }
 );
 
@@ -733,7 +731,7 @@ export const ZodNumberFormat: core.$constructor<ZodNumberFormat> = /*@__PURE__*/
   "ZodNumberFormat",
   (inst, def) => {
     core.$ZodNumberFormat.init(inst, def);
-    ZodType.init(inst, def);
+    ZodNumber.init(inst, def);
   }
 );
 
diff --git a/play.ts b/play.ts
index 4564a8e8..16d5045d 100644
--- a/play.ts
+++ b/play.ts
@@ -1,3 +1,5 @@
 import * as z from "zod";
 
 z;
+
+console.log(z.int().min(0).parse(234));


Test patch:
diff --git a/packages/zod/tests/number.test.ts b/packages/zod/tests/number.test.ts
index d8383c02..27ef999b 100644
--- a/packages/zod/tests/number.test.ts
+++ b/packages/zod/tests/number.test.ts
@@ -242,3 +242,9 @@ test("int getter", () => {
 test("finite getter", () => {
   expect(z.number().isFinite).toEqual(true);
 });
+
+test("string format methods", () => {
+  const a = z.int32().min(5);
+  expect(a.parse(6)).toEqual(6);
+  expect(() => a.parse(1)).toThrow();
+});