addamsson - I have the following code:tsimpor...
I have the following code:
My problem is no matter what I do or where I place that
refine
I never get the from
/to
error. What am I doing wrong?37 Replies
Why do you have
path: ['interval']
?
I don't see any field called interval there. path
is supposed to be "the path this error should be attached to"
You should pick either from
or to
, and change the path and the message to make sense of it. If your path is to
, then the message should be related to to
, like "To cannot be less than From", or whateverIt fails even if I remove that, I just tried some things out hoping that something will work
I also tried
zod-validation-error
but it does literally nothing lol
i mean it ignores from/to as wellYou can't remove it, you have to change the path to target an actual field
i mean
I'm looking at the docs:
and it doesn't say anything about
path
it says I can use it but nothing happens regardless
I dont' see this error in the outputah, no, because there it's just on a string. In your case you refine an object, so you should provide a path to the field the message should be attached to.
Ah, sorry, you mean the validation doesn't even fail at all?
i haven't checked that, i'm just looking at the resulting error, and it doesn't contain this message
what does it contain?
lemme paste it
this is the result of
flatten()
but if I introspect the object I don't see it still
so it is not an issue with flatten()
Right, so the nice/annoying thing about
zod
is that the validation happens in "stages", so when you have an object, with a refine, the object must be completely valid before the refine even happensdamn
that's bad
So if you make all the fields in the object valid first, then you should see the refine error
I.e. all fields are valid, and to and from are numbers, then refine should kick in and check if to and from are OK in relation to each other
the problem is that if the user supplies a negative age, and a bad from/to then i can only display the
age
problem, and when they fix it they'll bump into from
/to
which is bad uxYeah. Zod schemas is great for consistency and predictability, and awesome for parsing and validating data. But at least I found that the moment you need to report errors to users in the context of forms, and you have fields that depend on each other, then zod becomes cumbersome and annoying pretty quickly.
bummer
We have some form and wizard stuff built on top of
react-hook-form
and started with zod
for validation, and it's great for small simple forms, but yeah, for more complicated stuff with interdependent fields, the refine stuff became super annoying.i have like 100 zod schemas in my project lol π
So we ended up trying out
yup
instead for that, and it's a bit more janky, and I definitely don't trust its types as much as I do zod
, but it has a .when
feature which is pretty great for these kind of "if this field is that, then this field should validate this way, except if, blah blah"-cases
We're still using zod
to validate API responses, JSON configs and data we store in localStorage though, so we actually have both zod
and yup
in the same projecthm
It's easy to think that we need to use a single thing for every thing, but why not just pull in a couple of alternatives and use them for what they're best at π€·ββοΈ
i used io-ts before
migrated to zod before the simplicity
then someone suggested this: https://github.com/Effect-TS/schema
GitHub
GitHub - Effect-TS/schema: Modeling the schema of data structures a...
Modeling the schema of data structures as first-class values - GitHub - Effect-TS/schema: Modeling the schema of data structures as first-class values
have you used this before?
We use
yup
for complicated forms, and zod
for everything else. Has worked pretty well so far πwell if you input fp-ts or effect into that you'll get similar numbers probably
yet i found both superior to literally everything else
so these numbers aren't really useful
but maybe it makes sense if i use zod on the backend and something else on the frontend for complex stuff
For professional projects, I much rather use something not dead with high fairly long term usage, than a tiny project that is barely used by anyone, and very likely might be abandoned in a few months. Doesn't matter if the project is superior, if nobody else uses it, it's just maintained by a single person, and it's likely to die. π
Anyways, I'd recommend not throwing away
zod
just because it's not optimal for these complex things. I'd just keep using zod
for what it's great at, and find an alternative for the complex stuff. yup
as worked pretty well for us, but there are probably other good alternatives as welljust because not many folks are using it doesn't mean that it is dead / dying. I have been using fp-ts for a very long time and the contributors are very active. as long as you're using someone else's code there is always a chance that it will be abandoned at some point. not even big projects are free of this issue (just think about all the projects google killed).
Yeah, of course not. I'm not saying usage numbers is the only metric, just that it's a good one to have part of the decision making. Others are how long the project have been going, how active the maintainers are, number and age of open PRs and issues that, etc., etc.
Anyways, back to work for me π
π
I can weigh in here a bit: effect and effect/schema are great tools, and I would recommend them just based on their pedigree, but I don't have any practical experience with them. I would imagine they would suffer from this same "stages" issue though, due to how types need to propagate from the individual properties of an object then to the object itself: what would the type of
refine
's input be if we didn't know the types of the properties? Others have suggested having some function that lets you use unknown
here, but lemme tell you: it'll be a nightmare in practice to handle unknown
in a safe and consistent wayβthis is why Zod exists in the first place π
Yup makes the tradeoff of safety for flexibility and I think that's usually the right call for very complex forms: better UX and using a Zod schema server-side to re-parse the values to ensure safety. Some code duplication and syncing effort involved, for sure, but I agree with @Svish that it's really the right call a lot of the time.
FWIW, I think this is something that form frameworks can solve by introspecting the schema and cleverly constructing "valid" objects with fallbacks and collecting the refinement errors, etc, but none have yet added this level of integration.unknown
is indeed a pain to deal with, I'm just thinking that some sort of .extraValidation(value: unknown, ctx; ZodContextThatYouCanAddIssuesTo): void
function could add that little bit extra flexibility and allow people who do want to deal with the pain, rather than pulling in a whole other validation library, to keep using zod
.
Maybe it could have a very minor validation before running to narrow down the input type somewhat still. Like, if you use it on object
, it would check that the input value is an object, but give no guarantee whatsoever at what the object contains. Then you could do something along the lines of if('to' in value && 'from' in value && to < from) ctx.addIssue(...)
Even if left as unknown
, it's not that terrible to write a simple type-guard ourselves for whatever we need. Could technically even use zod
within zod
πYeah, the zod-in-zod approach is how I used preprocess and it has it's basically reintroduces the "stages" but gives you some flexibility to use
safeParse
.Yeah, but some sort of
.extraValidation
that you could attach to any schema that was called regardless and just let you add issues to the context, without affecting the data or types at all, I think could solve some of these issues people have with form validation. Of course it won't be super optimal or give great DX, but it could give you a way to solve some of these simpler cases.Maybe something like
finally(value, ctx)
?
where value: unknown
Yeah, something like that, is what I'm thinking at least
If at all possible, maybe the bare minimum of validation on the value. Like if it's on
ZodString
, validate that it's a string at least. And if it's on ZodObject
, validate that it's the bare minimum of an object.
But yeah, main focus that it should not mess with any typings or existing functionality in any wayI think that would be introduce subtle cases where you still don't get the
finally
firing (because your provided a number or null for instance) and therefore end up back in this same thing where some errors aren't present until data is in a certain shape, which does move the issue "back" a bit and lets more cases through, but doesn't seem worth introducing if it doesn't give you the tools to get the right UX you're after still.Yeah, good point. Best keep it simple and
unknown
π