You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Add typed callback function after parsing discriminate union #4019
Hi there, been using the library recently and love the typesafety! I have come across a use case though that I'm not sure how to go about, do let me know if there is some way to achieve it in the library, I am very new to using Zod
Following the example in the docs, I feel that there should be a way to type the parsed value for a discriminate union (not sure if the same can be applied for unions). Although I have parsed the value through my discriminate union schema, I have no type knowledge of what the value is although I believe, the parser has identified which of the items they are.
Current API
constmyUnion=z.discriminatedUnion("status",[z.object({status: z.literal("success"),data: z.string()}),z.object({status: z.literal("failed"),error: z.instanceof(Error)}),]);constparsedData=myUnion.parse({status: "success",data: "yippie ki yay"});// parsedData.data? not possible
Proposed API
Similar to a .then which maps the schema name to a callback that will be executed if that schema was used for validation. This way we are able to parse the unknown type using the validator and then actually use what we know about it!
constsuccess={status: z.literal("success"),data: z.string()}cosntfailed=z.object({status: z.literal("failed"),error: z.instanceof(Error)})constmyUnion=z.discriminatedUnion("status",[success,failed,]);constsuccessCallback=(s: success)=>{console.log(s.data)}constfailedCallback=(f: failed)=>{console.log(f.error)// console.log(f.data) will not work!}constparsedData=myUnion.parse({status: "success",data: "yippie ki yay"});parsedData.match({success: successCallback,failed: failedCallback})
Extra considerations
I think this probably will not be able to work on unions because a union might match multiple types therefore we are not able to know for sure what the actual item is? But for discriminateUnions which is the primary thing I am hoping this to be implemented for should be ok
Edit: I can see that if an object has nested discriminated types this might be quite a nightmare to handle. Not sure how this would be done
This seems like it's a limitation of TypeScript. When you do
constparsedData=myUnion.parse({status: "success",data: "yippie ki yay"});
parsedData is a discriminated union. You can't do parsedData.data because TypeScript doesn't know which union member this actually is. You would need to check that parsedData.status === "success" first.
You would end up with the same issue if you did this directly in TypeScript and didn't use Zod:
typeMyUnion={status: "success";data: string}|{status: "failed";error: Error};constdata={status: "success",data: "yippie ki yay"}asMyUnion;// Can access data.status but not data.data
If you wanted to run your callback functions after parsing, can you do
if (parsedData.status === "success") success(parsedData);
else failure(parsedData);
@BrendanC23 This was what I did in the end as well. Not too familiar with writing complex types like in Zod but just wondering if it would be possible to use conditional typing to infer what the return type is, if one of the schema was evaluated to be true?
Hi @BrendanC23 I was suggesting a solution to my original post. I was asking if it was possible to use conditional inference to give a return type which can be used in the callback api I suggested
Hi, @NicolasCwy. I'm Dosu, and I'm helping the Zod team manage their backlog. I'm marking this issue as stale.
Issue Summary:
You requested a feature to add a typed callback function for discriminated unions in Zod to enhance type safety.
@BrendanC23 suggested a workaround using TypeScript to check the status before executing callbacks.
You acknowledged the workaround but inquired about conditional typing for inferring return types in your proposal.
@BrendanC23 provided an example of extracting specific types from a discriminated union, but you sought further clarification.
Next Steps:
Please let us know if this issue is still relevant to the latest version of the Zod repository. If so, you can keep the discussion open by commenting on the issue.
Otherwise, the issue will be automatically closed in 14 days.
Thank you for your understanding and contribution!
Activity
[-]Add typed callback to discriminate union[/-][+]Add typed callback function after parsing discriminate union[/+]BrendanC23 commentedon Mar 6, 2025
This seems like it's a limitation of TypeScript. When you do
parsedDatais a discriminated union. You can't doparsedData.databecause TypeScript doesn't know which union member this actually is. You would need to check thatparsedData.status === "success"first.You would end up with the same issue if you did this directly in TypeScript and didn't use Zod:
If you wanted to run your callback functions after parsing, can you do
NicolasCwy commentedon Mar 11, 2025
@BrendanC23 This was what I did in the end as well. Not too familiar with writing complex types like in Zod but just wondering if it would be possible to use conditional typing to infer what the return type is, if one of the schema was evaluated to be true?
BrendanC23 commentedon Mar 11, 2025
You can do the following:
NicolasCwy commentedon Mar 12, 2025
Hi @BrendanC23 I was suggesting a solution to my original post. I was asking if it was possible to use conditional inference to give a return type which can be used in the callback api I suggested
dosubot commentedon Jul 24, 2025
Hi, @NicolasCwy. I'm Dosu, and I'm helping the Zod team manage their backlog. I'm marking this issue as stale.
Issue Summary:
Next Steps:
Thank you for your understanding and contribution!