Z
Zod•15mo ago
Steve

Hey people I am having some issue not

Hey people, I am having some issue, not sure how to resolve. Recursive types.
import {z} from "zod";


type CheckShell = {
type: "shell",
run: string
};


export const CheckShellSchema = z.object({
type: z.literal("shell"),
run: z.string().nonempty()
});

type CheckGroup = {
type: "group",
checks: Array<CheckShell | CheckGroup>
}

export const CheckGroupSchema = z.object({
type: z.literal("group"),
checks: z.lazy(
() => z
.discriminatedUnion(
"type",
[
CheckShellSchema,
CheckGroupSchema
]
)
.array()
.default([])
)
});

export type Config = {
earlyExitOnError: boolean,
earlyExitOnChanges: boolean,
checks: Array<CheckShell | CheckGroup>
}

export const ConfigSchema = z
.object({

earlyExitOnError: z.boolean().default(true),
earlyExitOnChanges: z.boolean().default(true),
checks: z
.discriminatedUnion(
"type",
[
CheckShellSchema,
CheckGroupSchema
]
)
.array()
.default([])
});
import {z} from "zod";


type CheckShell = {
type: "shell",
run: string
};


export const CheckShellSchema = z.object({
type: z.literal("shell"),
run: z.string().nonempty()
});

type CheckGroup = {
type: "group",
checks: Array<CheckShell | CheckGroup>
}

export const CheckGroupSchema = z.object({
type: z.literal("group"),
checks: z.lazy(
() => z
.discriminatedUnion(
"type",
[
CheckShellSchema,
CheckGroupSchema
]
)
.array()
.default([])
)
});

export type Config = {
earlyExitOnError: boolean,
earlyExitOnChanges: boolean,
checks: Array<CheckShell | CheckGroup>
}

export const ConfigSchema = z
.object({

earlyExitOnError: z.boolean().default(true),
earlyExitOnChanges: z.boolean().default(true),
checks: z
.discriminatedUnion(
"type",
[
CheckShellSchema,
CheckGroupSchema
]
)
.array()
.default([])
});
When building:
src/definitions.ts:20:14 - error TS7022: 'CheckGroupSchema' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

20 export const CheckGroupSchema = z.object({
~~~~~~~~~~~~~~~~


Found 1 error in src/definitions.ts:20
src/definitions.ts:20:14 - error TS7022: 'CheckGroupSchema' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.

20 export const CheckGroupSchema = z.object({
~~~~~~~~~~~~~~~~


Found 1 error in src/definitions.ts:20
11 Replies
Steve
SteveOP•15mo ago
cc @Scott Trinh
Scott Trinh
Scott Trinh•15mo ago
I think you'll need to split up CheckGroupSchema to a "base" and then extend it with the lazy schema, like in the example on zod.dev If you can throw this in a TypeScript playground, that'll be helpful for anyone wanting to provide some help
Steve
SteveOP•15mo ago
let me see If I can split
Scott Trinh
Scott Trinh•15mo ago
Importantly, to make the type recursive, you're required to provide the type of the final schema explicitly.
You can define a recursive schema in Zod, but because of a limitation of TypeScript, their type can't be statically inferred. Instead you'll need to define the type definition manually, and provide it to Zod as a "type hint"
Steve
SteveOP•15mo ago
Yeah When I do it more erros arrise unfortunately
Scott Trinh
Scott Trinh•15mo ago
share your updates (type errors are helpful and usually lead to the solution!)
Steve
SteveOP•4mo ago
I suspect it is in the discriminatedUnion one sec, let me debug both .default() and .discriminatedUnion() don't play well with lazy wait, that's because the types are input types It doesn't seem to bring me any errors @Scott Trinh Thanks, it works 😄 cc @Scott Trinh Encountered this issue again today. Is there a reason why .discriminatedUnion() with .lazy() doesn't seem to play nice? As soon as my object ofcourse get's wrapped by the lazy, it's not compatible anymore with type ZodDiscriminatedUnionOption<'type'> (where 'type' is my key for the discriminated union)
Scott Trinh
Scott Trinh•4mo ago
discriminatedUnion is a not-very-great optimization on union, so you might have to go with union to make it work.
Steve
SteveOP•4mo ago
Yeahh i feared that But it does make error messaging a lot more precise to my experience
Scott Trinh
Scott Trinh•4mo ago
oh, yeah, 100%. luckily, zod v4 will get us into a better place here where union will act like a discriminated union.
Want results from more Discord servers?
Add your server