Parsing a JSON string with zod #2215
-
|
I'm tired of writing the same try-catch code over and over again to parse JSON strings, and would love to parse it with something zod-like so it fits with the rest of my code. This is what I've come up with so far: const jsonSchema = z.string().refine((value) => {
try {
JSON.parse(value);
return true;
} catch (_) {
return false;
}
}).transform((value) => JSON.parse(value));Now I can do this: jsonSchema.parse('{"hello": "world"}') // {hello: "world"}
jsonSchema.safeParse('}') // {success: false, error: ZodError[...]}
jsonSchema.parse('}') // throws ZodErrorThis works great, awesome! But is there a way I can avoid calling |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 7 replies
-
Beta Was this translation helpful? Give feedback.
-
|
Just adding an alternative method of using const parseJsonPreprocessor = (value: any, ctx: z.RefinementCtx) => {
if (typeof value === 'string') {
try {
return JSON.parse(value);
} catch (e) {
ctx.addIssue({
code: ZodIssueCode.custom,
message: (e as Error).message,
});
}
}
return value;
};This can then be reused in multiple schemas like.. const someObjectShapeSchema = z.object({
foo: 'bar',
});
const someObjectSchema = z.preprocess(parseJsonPreprocessor, someObjectShapeSchema);
// Use as you normally would
someObjectSchema.parse('{"foo":"bar"}'); // { foo: 'bar' } |
Beta Was this translation helpful? Give feedback.
-
|
Zod v4 now has an inbuilt z.json() type. |
Beta Was this translation helpful? Give feedback.
-
|
With zod 4 it's possible to use const jsonString = z.string().pipe(
z.preprocess((input, ctx) => {
try {
return JSON.parse(input);
} catch (_) {
ctx.issues.push({ code: "custom", message: "Invalid JSON", input });
return z.NEVER;
}
}, z.json()),
);
jsonString.parse('{"omega":"kappa","number":42}');If you expect your json to be in a particular format, you can replace the const validator = z.object({
omega: z.string(),
number: z.number(),
});
const jsonString = z.string().pipe(
z.preprocess((input, ctx) => {
try {
return JSON.parse(input);
} catch (_) {
ctx.issues.push({ code: "custom", message: "Invalid JSON", input });
return z.NEVER;
}
}, validator),
);
jsonString.parse('{"omega":"kappa","number":42}'); |
Beta Was this translation helpful? Give feedback.
https://github.com/JacobWeisenburger/zod_utilz#stringtojson