diff --git a/packages/zod/src/helpers/partialUtil.ts b/packages/zod/src/helpers/partialUtil.ts index f1789ba58..94f0f4849 100644 --- a/packages/zod/src/helpers/partialUtil.ts +++ b/packages/zod/src/helpers/partialUtil.ts @@ -1,13 +1,13 @@ -import type { - ZodArray, - ZodNullable, - ZodObject, - ZodOptional, - ZodRawShape, - ZodTuple, - ZodTupleItems, - ZodTypeAny, -} from "../index.js"; +// import type { +// ZodArray, +// ZodNullable, +// ZodObject, +// ZodOptional, +// ZodRawShape, +// ZodTuple, +// ZodTupleItems, +// ZodTypeAny, +// } from "../index.js"; // export type DeepPartial = T extends AnyZodObject // ? ZodObject< @@ -34,29 +34,29 @@ import type { // ? "object" // T extends ZodOptional // ? 'optional' // : // : "rest"]; -export type DeepPartial = T extends ZodObject - ? ZodObject< - { [k in keyof T["shape"]]: ZodOptional> }, - T["_def"]["unknownKeys"], - T["_def"]["catchall"] - > - : T extends ZodArray - ? ZodArray, Card> - : T extends ZodOptional - ? ZodOptional> - : T extends ZodNullable - ? ZodNullable> - : T extends ZodTuple - ? { - [k in keyof Items]: Items[k] extends ZodTypeAny - ? DeepPartial - : never; - } extends infer PI - ? PI extends ZodTupleItems - ? ZodTuple - : never - : never - : T; +// export type DeepPartial = T extends ZodObject +// ? ZodObject< +// { [k in keyof T["shape"]]: ZodOptional> }, +// T["_def"]["unknownKeys"], +// T["_def"]["catchall"] +// > +// : T extends ZodArray +// ? ZodArray, Card> +// : T extends ZodOptional +// ? ZodOptional> +// : T extends ZodNullable +// ? ZodNullable> +// : T extends ZodTuple +// ? { +// [k in keyof Items]: Items[k] extends ZodTypeAny +// ? DeepPartial +// : never; +// } extends infer PI +// ? PI extends ZodTupleItems +// ? ZodTuple +// : never +// : never +// : T; // { // // optional: T extends ZodOptional ? T : ZodOptional; // // array: T extends ZodArray ? ZodArray> : never; diff --git a/packages/zod/src/types.ts b/packages/zod/src/types.ts index 36edf5daf..7b1fb890d 100644 --- a/packages/zod/src/types.ts +++ b/packages/zod/src/types.ts @@ -14,7 +14,6 @@ import { type enumUtil, errorUtil, type objectUtil, - type partialUtil, } from "./helpers/index.js"; import { @@ -2702,38 +2701,38 @@ export type noUnrecognized = { [k in keyof Obj]: k extends keyof Shape ? Obj[k] : never; }; -function deepPartialify(schema: ZodTypeAny): any { - if (schema instanceof ZodObject) { - const newShape: any = {}; - - for (const key in schema.shape) { - const fieldSchema = schema.shape[key]; - newShape[key] = ZodOptional.create(deepPartialify(fieldSchema)); - } - return new ZodObject({ - ...schema._def, - shape: () => newShape, - }) as any; - } - if (schema instanceof ZodArray) { - return new ZodArray({ - ...schema._def, - type: deepPartialify(schema.element), - }); - } - if (schema instanceof ZodOptional) { - return ZodOptional.create(deepPartialify(schema.unwrap())); - } - if (schema instanceof ZodNullable) { - return ZodNullable.create(deepPartialify(schema.unwrap())); - } - if (schema instanceof ZodTuple) { - return ZodTuple.create( - schema.items.map((item: any) => deepPartialify(item)) - ); - } - return schema; -} +// function deepPartialify(schema: ZodTypeAny): any { +// if (schema instanceof ZodObject) { +// const newShape: any = {}; + +// for (const key in schema.shape) { +// const fieldSchema = schema.shape[key]; +// newShape[key] = ZodOptional.create(deepPartialify(fieldSchema)); +// } +// return new ZodObject({ +// ...schema._def, +// shape: () => newShape, +// }) as any; +// } +// if (schema instanceof ZodArray) { +// return new ZodArray({ +// ...schema._def, +// type: deepPartialify(schema.element), +// }); +// } +// if (schema instanceof ZodOptional) { +// return ZodOptional.create(deepPartialify(schema.unwrap())); +// } +// if (schema instanceof ZodNullable) { +// return ZodNullable.create(deepPartialify(schema.unwrap())); +// } +// if (schema instanceof ZodTuple) { +// return ZodTuple.create( +// schema.items.map((item: any) => deepPartialify(item)) +// ); +// } +// return schema; +// } export class ZodObject< T extends ZodRawShape, @@ -3151,9 +3150,9 @@ export class ZodObject< /** * @deprecated */ - deepPartial(): partialUtil.DeepPartial { - return deepPartialify(this) as any; - } + // deepPartial(): partialUtil.DeepPartial { + // return deepPartialify(this) as any; + // } partial(): ZodObject< { [k in keyof T]: ZodOptional }, diff --git a/packages/zod/tests/partials.test.ts b/packages/zod/tests/partials.test.ts index fa44267ab..19d5a1e07 100644 --- a/packages/zod/tests/partials.test.ts +++ b/packages/zod/tests/partials.test.ts @@ -3,7 +3,6 @@ import { expect, test } from "vitest"; import { util } from "../src/helpers/index.js"; import * as z from "../src/index.js"; -import { ZodNullable, ZodOptional } from "../src/index.js"; const nested = z.object({ name: z.string(), @@ -35,100 +34,110 @@ test("shallow partial parse", () => { }); }); -test("deep partial inference", () => { - const deep = nested.deepPartial(); - const asdf = deep.shape.array.unwrap().element.shape.asdf.unwrap(); - asdf.parse("asdf"); - type deep = z.infer; - type correct = { - array?: { asdf?: string }[]; - name?: string | undefined; - age?: number | undefined; - outer?: { inner?: string | undefined } | undefined; - }; - - util.assertEqual(true); -}); - -test("deep partial parse", () => { - const deep = nested.deepPartial(); - - expect(deep.shape.name instanceof z.ZodOptional).toBe(true); - expect(deep.shape.outer instanceof z.ZodOptional).toBe(true); - expect(deep.shape.outer._def.innerType instanceof z.ZodObject).toBe(true); - expect( - deep.shape.outer._def.innerType.shape.inner instanceof z.ZodOptional - ).toBe(true); - expect( - deep.shape.outer._def.innerType.shape.inner._def.innerType instanceof - z.ZodString - ).toBe(true); -}); - -test("deep partial runtime tests", () => { - const deep = nested.deepPartial(); - deep.parse({}); - deep.parse({ - outer: {}, - }); - deep.parse({ - name: "asdf", - age: 23143, - outer: { - inner: "adsf", - }, - }); -}); - -test("deep partial optional/nullable", () => { - const schema = z - .object({ - name: z.string().optional(), - age: z.number().nullable(), - }) - .deepPartial(); - - expect(schema.shape.name.unwrap()).toBeInstanceOf(ZodOptional); - expect(schema.shape.age.unwrap()).toBeInstanceOf(ZodNullable); -}); - -test("deep partial tuple", () => { - const schema = z - .object({ - tuple: z.tuple([ - z.object({ - name: z.string().optional(), - age: z.number().nullable(), - }), - ]), - }) - .deepPartial(); - - expect(schema.shape.tuple.unwrap().items[0].shape.name).toBeInstanceOf( - ZodOptional - ); -}); - -test("deep partial inference", () => { - const mySchema = z.object({ - name: z.string(), - array: z.array(z.object({ asdf: z.string() })), - tuple: z.tuple([z.object({ value: z.string() })]), - }); - - const partialed = mySchema.deepPartial(); - type partialed = z.infer; - type expected = { - name?: string | undefined; - array?: - | { - asdf?: string | undefined; - }[] - | undefined; - tuple?: [{ value?: string }] | undefined; - }; - util.assertEqual(true); -}); +// test("deep partial inference", () => { +// const deep = nested.deepPartial(); +// const asdf = deep.shape.array.unwrap().element.shape.asdf.unwrap(); +// asdf.parse("asdf"); +// type deep = z.infer; +// type correct = { +// array?: { asdf?: string }[]; +// name?: string | undefined; +// age?: number | undefined; +// outer?: { inner?: string | undefined } | undefined; +// }; + +// util.assertEqual(true); +// }); + +// test("deep partial parse", () => { +// const deep = nested.deepPartial(); + +// expect(deep.shape.name instanceof z.ZodOptional).toBe(true); +// expect(deep.shape.outer instanceof z.ZodOptional).toBe(true); +// expect(deep.shape.outer._def.innerType instanceof z.ZodObject).toBe(true); +// expect( +// deep.shape.outer._def.innerType.shape.inner instanceof z.ZodOptional +// ).toBe(true); +// expect( +// deep.shape.outer._def.innerType.shape.inner._def.innerType instanceof +// z.ZodString +// ).toBe(true); +// }); + +// test("deep partial runtime tests", () => { +// const deep = nested.deepPartial(); +// deep.parse({}); +// deep.parse({ +// outer: {}, +// }); +// deep.parse({ +// name: "asdf", +// age: 23143, +// outer: { +// inner: "adsf", +// }, +// }); +// }); + +// test("deep partial optional/nullable", () => { +// const schema = z +// .object({ +// name: z.string().optional(), +// age: z.number().nullable(), +// }) +// .deepPartial(); + +// expect(schema.shape.name.unwrap()).toBeInstanceOf(ZodOptional); +// expect(schema.shape.age.unwrap()).toBeInstanceOf(ZodNullable); +// }); + +// test("deep partial tuple", () => { +// const schema = z +// .object({ +// tuple: z.tuple([ +// z.object({ +// name: z.string().optional(), +// age: z.number().nullable(), +// }), +// ]), +// }) +// .deepPartial(); + +// expect(schema.shape.tuple.unwrap().items[0].shape.name).toBeInstanceOf( +// ZodOptional +// ); +// }); + +// test("deep partial inference", () => { +// const mySchema = z.object({ +// name: z.string(), +// array: z.array(z.object({ asdf: z.string() })), +// tuple: z.tuple([z.object({ value: z.string() })]), +// }); + +// const partialed = mySchema.deepPartial(); +// type partialed = z.infer; +// type expected = { +// name?: string | undefined; +// array?: +// | { +// asdf?: string | undefined; +// }[] +// | undefined; +// tuple?: [{ value?: string }] | undefined; +// }; +// util.assertEqual(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); +// }); test("required", () => { const object = z.object({ @@ -240,13 +249,3 @@ test("partial with mask -- ignore falsy values", async () => { masked.parse({ country: "US" }); await masked.parseAsync({ country: "US" }); }); - -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); -});