Z
Zod10mo ago
Alex

Alex - Hi there, I am trying to validate a numb...

Hi there, I am trying to validate a number using zod. The number is first received as a string and could possibly be anything because it comes from a user input.
z.coerce.number().int("Invalid Value").positive("Must be a positive number").safeParse(maxQuantity);
z.coerce.number().int("Invalid Value").positive("Must be a positive number").safeParse(maxQuantity);
` This is my current schema, where maxQuantity is the said string. Now when I pass "d" as maxQuantity, I receive the error "Must be a positive number". How do I give an error that this is not even a number?
Solution:
``` z .string() .regex(/^[-]?\d*.?\d+$/, "Must be a number") .pipe(z.coerce.number().int("Must be an integer").positive("Must be a positive number"))...
Jump to solution
14 Replies
Scott Trinh
Scott Trinh10mo ago
You have to split the string parsing and the number refinement into two steps. Luckily with pipe, this is a little more elegant than the preprocess solution we had before. Something like this:
const NumberSchema = z
.string()
.regex(/^[-]?\d+$/)
.pipe(z.coerce.number().int().positive());
const NumberSchema = z
.string()
.regex(/^[-]?\d+$/)
.pipe(z.coerce.number().int().positive());
https://codesandbox.io/p/devbox/pedantic-breeze-v4cc7w
Alex
AlexOP10mo ago
cannot open the sandbox. what is that regex doing exactly? because I would expect my inital schema to give me an error because coerce should fail. also, because I get "Must be a positive number" as error, that means the int check was passed, which again means, coerce returned a number. that should not be the case, because coerce just uses the Number() constructor, which would give NaN when passing "d"
Scott Trinh
Scott Trinh10mo ago
Coerce just literally calls Number(val) which doesn't fail, just returns NaN
Alex
AlexOP10mo ago
correct, so how is the int check passing?
Scott Trinh
Scott Trinh10mo ago
That regex just ensures that the string is an integer-like thing I'm not sure, to be honest.
Alex
AlexOP10mo ago
I am also very confused, I will investigate further, just wanted to check I am not doing something obvious wrong
Scott Trinh
Scott Trinh10mo ago
fwiw, when I try to run it in the codesandbox, I do get the error for int with "d" as the input oh, actually I get expected number received nan as the error. for some reason I thought number accepted nan but maybe that's changed since the last time I looked at it
Alex
AlexOP10mo ago
maybe I am just reading one error for some reason, i will check nope, but still cannot access the code sandbox
Scott Trinh
Scott Trinh10mo ago
Ahh, here ya go: https://codesandbox.io/p/devbox/pedantic-breeze-v4cc7w?file=%2Fsrc%2Findex.ts%3A11%2C40 Wasn't up to speed on all the latest codesandbox changes to sharing and permissions.
Alex
AlexOP10mo ago
yes, works, thanks now using this, which works as I originally intended:
z
.string()
.regex(/^\d*\.?\d+$/, "Must be a number")
.pipe(z.coerce.number().int("Must be an integer").positive("Must be a positive number"))
.safeParse(maxQuantity);
z
.string()
.regex(/^\d*\.?\d+$/, "Must be a number")
.pipe(z.coerce.number().int("Must be an integer").positive("Must be a positive number"))
.safeParse(maxQuantity);
Scott Trinh
Scott Trinh10mo ago
Might want to tweak the regex to allow negative numbers so that you don't reject "-100" with "Must be a number", but yeah that seems about right!
Alex
AlexOP10mo ago
yes, true, thanks!
Solution
Alex
Alex10mo ago
z
.string()
.regex(/^[-]?\d*\.?\d+$/, "Must be a number")
.pipe(z.coerce.number().int("Must be an integer").positive("Must be a positive number"))
.safeParse(maxQuantity);
z
.string()
.regex(/^[-]?\d*\.?\d+$/, "Must be a number")
.pipe(z.coerce.number().int("Must be an integer").positive("Must be a positive number"))
.safeParse(maxQuantity);
Alex
AlexOP10mo ago
Thanks again, very helpfull!
Want results from more Discord servers?
Add your server