zod
zod copied to clipboard
add parseJson method
I am repeating this pattern quite a bit:
return z
.object({
articleOutlineMarkdown: z.string(),
ended: z.boolean(),
})
.parse(JSON.parse(articleOutlineUpdateJson));
I figured that since zod knows the schema, it could possibly parse it faster too?
@adaboese I find myself using the following pattern quite often
const zMyType = z.object({
something: z.string(),
// this pattern
json: z.string().transform((x, ctx) => {
try { return JSON.parse(x) } catch (e) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: e.message
})
return z.NEVER
}
}).pipe(...)
})
// ...
zMyType.parse({
something: 'hello',
json: '{ ... }'
})
Unfortunately, https://github.com/colinhacks/zod/issues/1309 went stale. I think the following would be the ideal pattern, personally, with the same implicit behaviour as the above:
const zMyType = z.object({
something: z.string(),
// this pattern
json: z.string().transform(x => JSON.parse(x)).pipe(...)
})
If https://github.com/colinhacks/zod/issues/1309 was supported, we could even use Zod schema types as .transforms themselves, similar to .pipe, but useful in more complex parsing use-cases where you need to unpack complex objects with different schemas.
A parseJson method seems trivial but in order to keep the API complete it would lead to four new functions: parseJson, safeParseJson, parseJsonAsync, safeParseJsonAsync.
There’s a potential here to also add some significant improvements over a two stage JSON-parse then Zod-parse. If you have an error in Zod, the context of that error is a path of property names. On the other hand, if the data originates in a JSON file, you could report the line number and character!
This feature is a must considering that LLMs deal with JSON data very well
For inspiration, check out Pydantic's Partial JSON Parsing
Any update on if parseJson will be added?
See also:
- https://github.com/colinhacks/zod/discussions/2215#discussioncomment-5356276
Another reason to support this in Zod is that the standard JSON parser does not support bigint, meaning you either have to write a workaround in the JSON parser to convert big integers to strings (and then back to bigint via .transform()...) or you have to use another library that supports it. If Zod supported parsing JSON directly, this scenario suddenly becomes trivial. At least, in one direction.
The main counterarguments I can see are these two:
- This drifts a little ways away from the point of Zod
- This would almost certainly lead to questions of "why doesn't Zod also support
stringify" (which has the same limitations)
I think these are fair reasons not to go this route. Zod does not really do any parsing, even though its main validation function is somewhat confusingly called .parse(). It's really just an extensible schema validator with some neat tooling on top of it. Parsing is therefore probably out of scope for this library.
Hi, @adaboese. I'm Dosu, and I'm helping the Zod team manage their backlog and am marking this issue as stale.
Issue Summary:
- You requested a new
parseJsonmethod in Zod to directly parse JSON strings with schemas, aiming for improved usability and performance. - Contributors shared workarounds using
.transformto parse JSON within schemas, highlighting common patterns already in use. - Some noted benefits like enhanced error reporting with JSON context and support for features such as bigint parsing.
- Maintainers expressed concerns about expanding Zod’s scope beyond schema validation into parsing, which could lead to scope creep.
- The discussion remains open without a definitive decision or implementation yet.
Next Steps:
- Please let me know if this feature is still relevant for your use case with the latest version of Zod by commenting on this issue.
- If there is no response within 7 days, I will automatically close this issue to keep the backlog manageable.
Thanks for your understanding and contribution!