Calling `isOptional` triggers preprocess callback
StefanTerdell opened this issue · 5 comments
Calling isOptional
triggers preprocess callback.
Related to StefanTerdell/zod-to-json-schema#23.
Here's a failing test case:
test("calling isOptional should not trigger preprocess function", () => {
let wasCalled = false;
const pre = z.preprocess(() => {
wasCalled = true;
}, z.string());
pre.isOptional();
expect(wasCalled).toBe(false);
});
Maybe it's not an easy fix - looking thru code
Line 439 in 4709160
If it's not possible to change, or if it's planned to work like this, this would be a documentation issue; in such a case it's needed to mention that .preprocess cb must be a pure function in docs
Thank you for looking into this
I believe this is "working as intended" and one of the gotchas for the preprocess
feature. Admittedly, preprocess
is not my favorite feature, but it does have its use cases and proponents. You can think of preprocess
as something that always runs when you interact with the schema at runtime, even if in some cases it doesn't I don't think we're likely to guarantee that any given method (or even property lookup!) won't run the preprocess first: sometimes we just want to safeParse
the schema! 😅
Going to close for now, but feel free to keep the conversation alive if you have any further thoughts.
I currently get by with transform
, with latest zod version it's a bit more useful for this case. My case being a string ${literal}${SEPARATOR}${brandedId}
to be parsed and accessible as {type: ...literal..., id: ...brandedId...}
and some similar shenanigans
@StefanTerdell is this the same problem as when using zod-to-json-schema with a schema such as this?
const schema = z.object({
name: z.string().min(1),
email: z
.string()
.optional()
.refine(async () => Promise.resolve(true))
});