-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Parse a boolean value represented by string logically #2985
Comments
If there is such a simple work around, then why should this be a part of zod core? |
@JacobWeisenburger Thank you for your feedback. My opinions are:
const envSchema = z.object({
SERVER_URL: z.string().min(5, {message: "Required"}),
SOMETHING_VALUE: z.string(),
EXPIRE_DAYS: z.coerce.number().default(30),
SOMETHING_NUMERIC_CONFIG: z.coerce.number().min(1),
DEBUG: z.string().boolean(),
ENABLE_SOMETHING: z.string().boolean(),
});
const env = envSchema.parse(Deno.env.toObject()); I beleave that it is not much complex implementation. Sorry for my previous comment with lack of understaing of the zod architecutre. Now I am deepdiving zod codes. |
This is a really good idea. I lost a couple hours of debugging today trying to figure out why "false" provided as a string to a ZOD parse function was resulting in "true" for a z.boolean() value. I know it is fault of Boolean('false') being truthy, but this is a foot gun. No one reasonable expects "false" to be parsed as Boolean true. |
@jlandowner this is both useful for environment variable parsing as well as URL query parameter parsing. It is incredibly common to have "feature=true" or "feature=false" on an URL and for that to parse as always "true" by default is sort of crazy. |
Also I should add that this bug isn't present with Joi. So when I converted over to Zod from Joi, this was a huge surprise. |
A really quick heads up, rather than invoking the entire z.string().toLowerCase().transform((x) => x === 'true').pipe(z.boolean()) |
This is what is working for me: z.enum(['true', 'false']).transform((value) => value === 'true') |
## Describe your changes - Zod can't coerce boolean colinhacks/zod#2985 I only tested with true-ish values, that what's you got when not fuzzing unit test - Do not log runner logs in Persist - Trace opensearch in datadog
I didn't find any working solutions for my use case (query params), but I modified one example from here
Now it does what I want. string "true" turns into boolean true, everything else is false and basically fails. EDIT: For my use-case, that actually was the wrong answer. I should have just done this:
This code won't fail on any input and just returns |
See #2989 (comment) |
I'm going to leave a comment here in case anyone has the same problem as me and finds this same GitHub issue on Google. I needed a schema that handles both boolean values and boolean strings such as
|
Like a charm! |
Workaround works with : const castStringToBool = z.preprocess((val) => {
if (typeof val === "string") {
if (['1', 'true'].includes(val.toLowerCase())) return true;
if (['0', 'false'].includes(val.toLowerCase())) return false;
}
return val;
}, z.coerce.boolean()); perfect for env vars |
The thing is you can not really re-use this if you'd like to do: |
Thank you @IlmariKu! This coercion finally worked for me today. |
Using the following schema, which is be better than
|
From #1630 (comment)
Currently
z.boolean()
simply replesentsBoolean()
for coerce. So it handles string value as boolean along with the standardBoolean()
specification.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean#boolean_coercion
However we often need to handle string as boolean,
"false"
or"0"
asfalse
, such as parsing environment valiables.Current workaround is like
My suggestion is a new string transformation:
z.string().boolean()
The transforming specification in Go standard library's
strconv.ParseBool()
is good for it.https://pkg.go.dev/strconv#ParseBool
The text was updated successfully, but these errors were encountered: