diff --git a/deno/lib/__tests__/partials.test.ts b/deno/lib/__tests__/partials.test.ts index 67fb82050..06fb29ba8 100644 --- a/deno/lib/__tests__/partials.test.ts +++ b/deno/lib/__tests__/partials.test.ts @@ -270,3 +270,13 @@ test("partial with mask containing a nonexistent key", () => { doesntExist: true, }); }); + +test("deeppartial array", () => { + const schema = z.object({ array: z.string().array().min(42) }).deepPartial(); + + // works as expected + schema.parse({}); + + // should be false, but is true + expect(schema.safeParse({ array: [] }).success).toBe(false); +}); diff --git a/deno/lib/types.ts b/deno/lib/types.ts index 7e38cd6ea..eea43823c 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -2226,7 +2226,10 @@ function deepPartialify(schema: ZodTypeAny): any { shape: () => newShape, }) as any; } else if (schema instanceof ZodArray) { - return ZodArray.create(deepPartialify(schema.element)); + return new ZodArray({ + ...schema._def, + type: deepPartialify(schema.element), + }); } else if (schema instanceof ZodOptional) { return ZodOptional.create(deepPartialify(schema.unwrap())); } else if (schema instanceof ZodNullable) { @@ -3781,7 +3784,7 @@ export class ZodFunction< return this._def.returns; } - args[0]>( + args[0]>( ...items: Items ): ZodFunction, Returns> { return new ZodFunction({ @@ -4919,18 +4922,18 @@ const oboolean = () => booleanType().optional(); export const coerce = { string: ((arg) => - ZodString.create({ ...arg, coerce: true })) as typeof ZodString["create"], + ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)["create"], number: ((arg) => - ZodNumber.create({ ...arg, coerce: true })) as typeof ZodNumber["create"], + ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)["create"], boolean: ((arg) => ZodBoolean.create({ ...arg, coerce: true, - })) as typeof ZodBoolean["create"], + })) as (typeof ZodBoolean)["create"], bigint: ((arg) => - ZodBigInt.create({ ...arg, coerce: true })) as typeof ZodBigInt["create"], + ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)["create"], date: ((arg) => - ZodDate.create({ ...arg, coerce: true })) as typeof ZodDate["create"], + ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)["create"], }; export { diff --git a/playground.ts b/playground.ts index afbfa720c..e60b11276 100644 --- a/playground.ts +++ b/playground.ts @@ -1,6 +1,14 @@ import { z } from "./src"; -z.number().catch((ctx) => { - ctx; -}); -export const arg = j.parse({}); +const schema = z.object({ array: z.string().array().min(42) }).deepPartial(); + +console.log(schema.shape.array._def); +console.log(schema.shape.array._def.innerType._def.minLength); + +// works as expected +console.log(schema.safeParse({}).success); // true + +// should be false, but is true +console.log(schema.safeParse({ array: [] }).success); // true + +console.log(z.string().array().min(42).safeParse([]).success); diff --git a/src/__tests__/partials.test.ts b/src/__tests__/partials.test.ts index f6d7fcf7d..d716b4471 100644 --- a/src/__tests__/partials.test.ts +++ b/src/__tests__/partials.test.ts @@ -269,3 +269,13 @@ test("partial with mask containing a nonexistent key", () => { doesntExist: true, }); }); + +test("deeppartial array", () => { + const schema = z.object({ array: z.string().array().min(42) }).deepPartial(); + + // works as expected + schema.parse({}); + + // should be false, but is true + expect(schema.safeParse({ array: [] }).success).toBe(false); +}); diff --git a/src/types.ts b/src/types.ts index c4831288c..c0a1459a6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2226,7 +2226,10 @@ function deepPartialify(schema: ZodTypeAny): any { shape: () => newShape, }) as any; } else if (schema instanceof ZodArray) { - return ZodArray.create(deepPartialify(schema.element)); + return new ZodArray({ + ...schema._def, + type: deepPartialify(schema.element), + }); } else if (schema instanceof ZodOptional) { return ZodOptional.create(deepPartialify(schema.unwrap())); } else if (schema instanceof ZodNullable) { @@ -3781,7 +3784,7 @@ export class ZodFunction< return this._def.returns; } - args[0]>( + args[0]>( ...items: Items ): ZodFunction, Returns> { return new ZodFunction({ @@ -4919,18 +4922,18 @@ const oboolean = () => booleanType().optional(); export const coerce = { string: ((arg) => - ZodString.create({ ...arg, coerce: true })) as typeof ZodString["create"], + ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)["create"], number: ((arg) => - ZodNumber.create({ ...arg, coerce: true })) as typeof ZodNumber["create"], + ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)["create"], boolean: ((arg) => ZodBoolean.create({ ...arg, coerce: true, - })) as typeof ZodBoolean["create"], + })) as (typeof ZodBoolean)["create"], bigint: ((arg) => - ZodBigInt.create({ ...arg, coerce: true })) as typeof ZodBigInt["create"], + ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)["create"], date: ((arg) => - ZodDate.create({ ...arg, coerce: true })) as typeof ZodDate["create"], + ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)["create"], }; export {