import * as vi from "vitest"
import { zx } from "@traversable/zod"
// Using `zx.deepOptional.writeable` here to make it easier to visualize `zx.deepOptional`'s behavior:
vi.expect.soft(zx.deepOptional.writeable(
z.object({
a: z.number(),
b: z.string(),
c: z.object({
d: z.tuple([
z.bigint(),
z.object({
e: z.number().max(1),
f: z.boolean()
}),
])
})
})
)).toMatchInlineSnapshot
(`
"z.object({
a: z.number().optional(),
b: z.string().optional(),
c: z.object({
d: z.tuple([
z.bigint().optional(),
z.object({
e: z.number().max(1).optional(),
f: z.boolean().optional()
}).optional()
]).optional()
}).optional()
})"
`)
zx.deepOptionalRecursively wraps every node in your zod schema with z.optional
z.optional.That just means that the schema will be traversed, and wrap all z.object
z.objectproperties with z.optionalz.optional.Options
zx.deepOptional's behavior is configurable at the typelevel via the defaults.typeleveloptions.typelevelproperty:defaults.typelevel
"semantic"(default): leave the schema untouched, but wrap it in a no-op interface (zx.deepOptional.Semantic) to make things explicitdefaults.typelevel
"applyToTypesOnly": apply the transformation to the schema's output type and wrap it in z.ZodTypez.ZodTypedefaults.typelevel
"preserveSchemaType":zx.deepOptionalwill return what it got, type untouched