@traversable/schema
    Preparing search index...

    Type Alias deepNullable<T, Atom>

    deepNullable: T extends Primitive
        ? T
        : T extends Atom
            ? T
            : T extends readonly unknown[]
                ? { [I in keyof T]: deepNullable<T[I], Atom> }
                : T extends object
                    ? { -readonly [K in keyof T]: null
                    | deepNullable<T[K], Atom> }
                    : T

    Converts an arbitrary zod schema into its "deeply-partial" form.

    That just means that the schema will be traversed, and wrap all z.object z.object properties with z.nullable z.nullable.

    Any properties that were already nullable will be left as-is, since re-wrapping again doesn't do anything except make the schema's type harder to read.

    zx.deepNullable'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.deepNullable.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.deepNullable will return what it got, type untouched

    Type Parameters

    import * as vi from "vitest"
    import { z } from "zod"
    import { zx } from "@traversable/zod"

    // Using `zx.deepNullable.writeable` here to make it easier to visualize `zx.deepNullable`'s behavior:
    vi.expect.soft(zx.deepNullable.writeable(
    z.object({
    a: z.number(),
    b: z.nullable(z.string()),
    c: z.object({
    d: z.array(z.object({
    e: z.number().max(1),
    f: z.boolean()
    })).length(10)
    })
    })
    )).toMatchInlineSnapshot
    (`
    "z.object({
    a: z.number().nullable(),
    b: z.string().nullable(),
    c: z.object({
    d: z.array(z.object({
    e: z.number().max(1).nullable(),
    f: z.boolean().nullable()
    })).length(10).nullable()
    }).nullable()
    })"
    `)