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.deepOptional
Recursively 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.object
properties with z.optionalz.optional
.Options
zx.deepOptional
's behavior is configurable at the typelevel via the defaults.typeleveloptions.typelevel
property: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.ZodType
defaults.typelevel
"preserveSchemaType"
:zx.deepOptional
will return what it got, type untouched