-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there a way to combine discriminatedUnion
with lazy
?
#1504
Comments
One option here is to make type MyUnion =
| z.infer<typeof someOtherObjectWithADiscriminatingType>
| RecursiveElement; // Can't use z.infer here, use explicit type
const myUnion: z.ZodType<MyUnion> = z.lazy(() =>
z.discriminatedUnion("type", [
recursiveElement,
someOtherObjectWithADiscriminatingType
]),
);
const someOtherObjectWithADiscriminatingType = z.object({
type: z.literal("some-other-type"),
randomProperty: z.string(),
});
const recursiveElement = z.object({
type: z.literal("recursive-element"),
children: myUnion.array(),
}); // With TS 4.9, could add `satisfies z.ZodType<RecursiveElement>` here
type RecursiveElement = {
type: "recursive-element";
children: MyUnion[]
} (Edited to fix code) In my experience this works nicely, because you only ever have one lazy schema (the union), even if you add additional recursive union elements. |
This does not work for me. I cannot define recursiveElement without lazy. |
I'm not sure if you have some different limitation that you're not describing, but I did realize my above suggestion was mistaken. You must additionally write a manual type definition for the type MyUnion =
| z.infer<typeof someOtherObjectWithADiscriminatingType>
| RecursiveElement; // Can't use z.infer here, use explicit type
const myUnion: z.ZodType<MyUnion> = z.lazy(() =>
z.discriminatedUnion("type", [
recursiveElement,
someOtherObjectWithADiscriminatingType
]),
);
const someOtherObjectWithADiscriminatingType = z.object({
type: z.literal("some-other-type"),
randomProperty: z.string(),
});
const recursiveElement = z.object({
type: z.literal("recursive-element"),
children: myUnion.array(),
}); // With TS 4.9, could add `satisfies z.ZodType<RecursiveElement>` here
type RecursiveElement = {
type: "recursive-element";
children: MyUnion[]
} This definitely works (I've used this pattern myself). Do you have some other reason why you can't define |
I've got this openned PR #1290 fixing this issue and waiting for feed back or merge. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
See also this Stack Overflow answer that provides a different solution. |
Hello,
I stumbled on this problem.
When using lazy (recursive types) I cannot use discriminatedUnion anymore.
What works is
But I would love to use
discriminatedUnion
here.Any way I can type lazy object recursiveElement somehow that it does not throw an error?
Here is this problem in CodeSandBox: https://codesandbox.io/s/lucid-wilson-k5x1pu?file=/src/App.tsx:682-792
The text was updated successfully, but these errors were encountered: