-
-
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
Add z.string().json(...) helper #3109
Conversation
✅ Deploy Preview for guileless-rolypoly-866f8a ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
src/types.ts
Outdated
ctx.addIssue({ | ||
code: ZodIssueCode.invalid_string, | ||
validation: "json", | ||
message: (error as Error).message, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With a quick scan, can't find anywhere else where error as Error
is used.
So if you need it to be a message: string
, check for instanceof
first, or use the ...errorUtil.errToObj
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO as
is better here than doing something at runtime. JSON.parse(...)
only throws Error
s (specifically SyntaxError
s) as documented by MDN. I also don't feel particularly strongly though.
@colinhacks any thoughts on this? |
Thanks, great stuff. I'm merging this into the |
@colinhacks what would be the feature of a |
Yes, a schema that encapsulates the const schema = z.json(z.object({ name: z.string() }))
schema.parse(`{ "name": "Maarten" }`) |
* Add z.string().json(...) helper * use parseAsync + await expect(...).rejects * make it work in deno * Add overload --------- Co-authored-by: Misha Kaletsky <mmkal@users.noreply.github.com> Co-authored-by: Colin McDonnell <colinmcd94@gmail.com>
That looks clean, however would that not be this: (?) const jsonStr = `{ "name": "Jhon Doe" }`;
const schema = z.object({
name: z.string(),
});
const anyJsonObj: unknown = JSON.parse(jsonStr);
const parsed = schema.parse(anyJsonObj);
// ^? type: z.infer<typeof schema> I could be wrong, but the So by making this 'replacement' as to call it, would you not need way more steps to have the same, generic, result? |
Was just going to comment re: this, it would be good to have a method like const Config = z.json(
z.object({
apiKey: z.string(),
templateId: z.string(),
})
).reviver((k, v) => typeof v === 'number' ? v.toString() : v)
const result = Config.parse(process.env.CONFIG) // '{"apiKey":"x", "templateId":123}' => {apiKey: 'x', templateId: '123'} You could often achieve a similar result with But @m10rten it's not really the same as calling const BigSchema = z.object({
type: z.string(),
foo: z.number(),
env: z.object({
NODE_ENV: z.string(),
CONFIG: z.json(z.object({apiKey: z.string()})).reviver(...)
}),
}) |
Based on #3077 (comment). I started playing around to see how quick it would be to implement, and it ended up being very quick - so opening a PR in hopes the idea is accepted.
Copying from the readme for the
z.string().json(...)
method - the linked issue has more details on the motivation:JSON
The
z.string().json(...)
method parses strings as JSON, then pipes the result to another specified schema.If invalid JSON is encountered, the syntax error will be wrapped and put into a parse error:
This is recommended over using
z.string().transform(s => JSON.parse(s))
, since that will not catch parse errors, even when using.safeParse
.