Bence (Arzen) - Hey guys 🙂I have a (might be)...
Hey guys 🙂
I have a (might be) silly question.
I have a schema exported as module:
It is being imported and used in another schema like so:
I am using
react-hook-form
with zodResolver
and the validation error for the name
field is the following: Required
Keep it in mind, that mySchema
in the example above is being used at many places but the form field name could be different.
Is there a way I could customise the error message on the imported schema
?
something like:
11 Replies
good question. is it truly something as simple as a
z.string()
object or is it more complicated than that normally?
The typical way to resolve this is to add an error map, but if you're returning a schema object, I don't think there is a way to add an error map once the schema has been created.You can with a global error map, but only if the schema doesn't specify error messages explicitly. I think... maybe you can override it as well, not sure.
well, i think the use case here is overriding it when it's used, rather than globally.
ah, I see
Or maybe you can?
https://zod.dev/ERROR_HANDLING?id=contextual-error-map
Yeah you can add it when you make a schema, but not to a schema object that has already been created (
string
vs string()
)
We need a clone
method
You might be able to refactor the export to export a factory rather than an instance though. Depends on how arbitrarily complex these schemas are 😅
Like if it's just string
export that schema constructor instead of an instance, you know?
But I suspect these are instances with complex validations on themProbably. But yeah, it seems you can pass an error map when you use the schema, passing it to the
.parse
function. So maybe that's a middleground between using a global error map, and not being able to pass it to already created schemas 🤷♂️@here sorry for the late reply. I didn't get any notification from the server for some reason.
The schema I am trying to override the error on is indeed simple.
I'll get you guys some code example how it's being created then how I try to use it later in our codebase.
Schema creation example:
I am using a couple of helper libraries which aren't really important to include here.
Then the way I create these types is the following:
Once I have the
userIdInstance
I can access the schema on it and safely wrap or unwrap any values.
The type we end up with is the following:
The way I use it is the following:
I don't think the global error map will work. I also tried to use refine
and superRefine
but if the example schema above (userIdSchema
) failes, it will not propogate anything to the refine/superRefine
block (as it is expected I believe)Well, not sure what to say here.
Personally this is one of the reasons why I shy away from too much abstraction and "helpers" in these cases, and why I lean heavily on generic error messages from a global error map instead of specifying them directly in our schemas. Less issues with types, less need for picking and adjusting existing schemas, and so on.
In your case, I'd consider just avoid the reuse and abstractions and just do:
I had a sort of "solution" but thought there is something better that I do not know of:
I understand your point of view.
My main reason why I want to enforce type safety and create reference and id types is to avoid passing in something unintended around my codebase and scratch my head why everything collapses.
My issues it type aliases in TS. Consider the following code:
I "understand" that we only created a type alias but coming from Scala I hate this behaviour 😂
Yeah... I highly recommend that you try to leave your nominal typing hangups in Scala, and instead embrace and get used to structural typing in js/ts. It has its downsides, but also several upsides.
A main source of terrible js/ts code is from backend people refusing to change their ways, making classes and interfaces for everything, and trying to recreate nominal typing in a language that does not support it
One thing I use sometimes instead of what you're doing there is something like this:
You can look into branded types, but yeah... Personally I prefer to try working with the language, rather than against it
Thank you for your insight! 🙂 It was very useful, I'll do my best to embrace what the language provides.