-
-
Notifications
You must be signed in to change notification settings - Fork 94
Description
My app uses true/false "boolean" string values (where only true/false should be accepted) as hidden fields in several forms (that just look like buttons to the user) which are used to toggle roles for a particular user. Each such form has two hidden fields — the name of the role and whether or not the user had it when the page was loaded (to prevent unexpected toggles when the role has already been added/removed server side after page load) — as well as a submit button that indicates the role being toggled.
I want to use z.stringbool()
, introduced in Zod v4, which is a convenient way to parse a string and convert it to a boolean while ensuring only certain values are accepted as truthy or falsy. In my case:
z.stringbool({
truthy: ['true'],
falsy: ['false'],
case: 'sensitive'
});
Unfortunately using z.stringbool()
as part of the schema that then gets passed to Superforms causes an issue because, as I understand it, Superforms detects that this is supposed to be a boolean type and thus uses its own parsing logic whereby all non-"false"
values by default evaluate to true
and Superforms passes an actual boolean value (not a string) to Zod, which results in the error Invalid input: expected string, received boolean
when parsing the submitted form data.
- This is not a desired outcome as validation using
z.stringbool()
should be successful when the input is set to"true"
or"false"
and fail otherwise - While using
z.boolean()
orz.coerce.boolean()
will not fail validation when true/false are used, it will also not fail if non-true/false values are used as once again all non-"false"
values will evaluate totrue
. - The only way the desired behavior can be achieved is using
z.enum(['true', 'false']).transform((value) => value === 'true');
however I would rather avoid this workaround as it is non-standard and not used throughout the rest of the project