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.optional z.optional
.
zx.deepOptional
's behavior is configurable at the typelevel via
the defaults.typelevel options.typelevel
property:
defaults.typelevel "semantic"
(default): leave the schema untouched, but wrap it
in a no-op interface (zx.deepOptional.Semantic
) to make things explicit
defaults.typelevel "applyToTypesOnly"
: apply the transformation to the schema's
output type and wrap it in z.ZodType z.ZodType
defaults.typelevel "preserveSchemaType"
: zx.deepOptional
will
return what it got, type untouched
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.optional z.optional
.
zx.deepOptional
's behavior is configurable at the typelevel via
the defaults.typelevel options.typelevel
property:
defaults.typelevel "semantic"
(default): leave the schema untouched, but wrap it
in a no-op interface (zx.deepOptional.Semantic
) to make things explicit
defaults.typelevel "applyToTypesOnly"
: apply the transformation to the schema's
output type and wrap it in z.ZodType z.ZodType
defaults.typelevel "preserveSchemaType"
: zx.deepOptional
will
return what it got, type untouched
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.optional z.optional
.
zx.deepOptional
's behavior is configurable at the typelevel via
the defaults.typelevel options.typelevel
property:
defaults.typelevel "semantic"
(default): leave the schema untouched, but wrap it
in a no-op interface (zx.deepOptional.Semantic
) to make things explicit
defaults.typelevel "applyToTypesOnly"
: apply the transformation to the schema's
output type and wrap it in z.ZodType z.ZodType
defaults.typelevel "preserveSchemaType"
: zx.deepOptional
will
return what it got, type untouched
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