coerce.boolean incorrect #3329
-
import { z } from 'zod';
const schema = z.object({
something: z.coerce.boolean(),
});
console.log(schema.parse({ something: 'false' })); expected:
got:
|
Beta Was this translation helpful? Give feedback.
Replies: 7 comments
-
Hello ! No, this behavior is normal. You can verify it by executing this code: console.log(Boolean("false")); // displays true You can do something like that: const booleanStringSchema = z.string().transform(value => {
if (value === "true") {
return true;
} else if (value === "false") {
return false;
} else {
throw new Error("The string must be 'true' or 'false'");
}
}); Regards. |
Beta Was this translation helpful? Give feedback.
-
I believe it's incorrect. Coercion should convert the string into the desired type. For example, coercing a boolean string 'false' should result in false, which is the expected behavior. |
Beta Was this translation helpful? Give feedback.
-
No, you are wrong. Go read the documentation: https://zod.dev/?id=coercion-for-primitives This is exactly what I explained to you. If you find these rules illogical, go blame javascript specification writers. ;) Regards. |
Beta Was this translation helpful? Give feedback.
-
I agree that the js spec is weird but do think one would assume coerce of string value true|false to work. Pretty common to use booleans in forms which transmit as strings but we want them to be proper booleans for the database. Transfrom didn't work for me in this use case but preprocess did like so:
The first conditional is needed because the types are checked on their way out of the database and have the boolean type. |
Beta Was this translation helpful? Give feedback.
-
Personally, I don't find these coercions rules weird. |
Beta Was this translation helpful? Give feedback.
-
@vtgn got me thinking and I was reviewing my giant diff with other changes this am. Decided only returning a value on boolean type or string value of "true" or "false". Anything else should throw the error like this.
|
Beta Was this translation helpful? Give feedback.
-
Also worth mentioning existing db values may be undefined. For my use case I just default it to true by adding || value === undefined to the value equal string true line. More important is an error here is an app error. You'll likely still want a validator with a nice user error message that ideally they will never encounter. |
Beta Was this translation helpful? Give feedback.
No, you are wrong.
This is normal that coerce method uses the standard javascript conversions rules.
Go read the documentation: https://zod.dev/?id=coercion-for-primitives
Particularly this part:
This is exactly what I explained to you.
If you find these rules illogical, go blame javascript specification writers. ;)
But if you want different conversion rules, you'll have to implement them yourself like in my previous example.
Regards.