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.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.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.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.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.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.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