I try to add yup
validation to my form which is built with react-hook-form
. I also use the standard components from @headlessui
to build my components. My usecase is the following:
If the Radio Input
is checked with "Yes"
the Text Input
should be required
, otherwise the Text Input
is optional
.
For some reason I can’t add conditional validation to my radio button
component. Maybe it has something todo with the Controller
Component of react-hook-form
.
I get the following error message:
Overload 1 of 4, '(keys: string | string[], builder: ConditionBuilder<StringSchema<string | undefined, AnyObject, undefined, "">>): StringSchema<string | undefined, AnyObject, undefined, "">', gave the following error.
Argument of type '{ is: string; then: yup.StringSchema<string, yup.AnyObject, undefined, "">; otherwise: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">; }' is not assignable to parameter of type 'ConditionBuilder<StringSchema<string | undefined, AnyObject, undefined, "">>'.
Object literal may only specify known properties, and 'is' does not exist in type 'ConditionBuilder<StringSchema<string | undefined, AnyObject, undefined, "">>'.typescript(2769)
This is my TestForm
component and here is also a codesandbox:
https://codesandbox.io/p/sandbox/nice-framework-vkx7k5?file=%2Fcomponents%2Fform%2FTest%2FTestForm.tsx%3A46%2C17
"use client";
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
import { Controller, useForm } from "react-hook-form";
import InputField from "../../ui/InputField";
import RadioGroupInput from "../../ui/RadioGroupInput";
import { useFormState } from "./TestFormContext";
const validationSchema = yup.object({
radioButtons: yup.string().required("Needed"),
textInput: yup.string().when("radioButtons", {
is: "Yes",
then: yup.string().required("Needed"),
otherwise: yup.string(),
}),
});
export type FirstPageFormData = yup.InferType<typeof validationSchema>;
export default function TestForm() {
const { setFormData, formData } = useFormState();
const {
register,
handleSubmit,
formState: { errors, isSubmitting, isLoading },
control,
getValues,
watch,
} = useForm<FirstPageFormData>({
defaultValues: formData,
resolver: yupResolver(validationSchema),
shouldFocusError: false,
});
const watchAllFields = watch();
async function onSubmit(data: FirstPageFormData) {
setFormData((formData) => ({ ...formData, ...data }));
alert(JSON.stringify(formData));
}
return (
<div>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="bg-white mt-6 px-4 py-5 shadow sm:rounded-lg sm:p-6">
<div className="col-span-6">
<Controller
name="radioButtons"
control={control}
rules={{
required: true,
}}
render={({ field }) => (
<RadioGroupInput
label="Radio Buttons"
type="ghost"
error={errors.radioButtons}
radioButtons={[
{
title: "Yes",
},
{
title: "No",
},
]}
field={field}
/>
)}
/>
</div>
<div className="col-span-6 sm:col-span-3">
<InputField
id="textInput"
name="textInput"
type="text"
label="Text Input"
register={register("textInput")}
error={errors.textInput}
/>
</div>
</div>
<div className="mt-4 flex justify-end gap-4">
<input
type="submit"
className="bg-gray-900 text-white p-2 rounded-md flex w-28 justify-center cursor-pointer hover:bg-gray-700"
disabled={isLoading}
value="Submit"
/>
</div>
</form>
<div>{JSON.stringify(watchAllFields)}</div>
</div>
);
}
I tried to use yup
with the following format
const validationSchema = yup.object({
radioButtons: yup.string().required("Needed"),
textInput: yup.string().when("radioButtons", {
is: "Yes",
then: yup.string().required("Needed"),
otherwise: yup.string(),
}),
});
and also in this format
const validationSchema = yup.object({
radioButtons: yup.string().required("Needed"),
textInput: yup.string().when("radioButtons", (val, schema) => {
if (val === "Yes") return yup.string().required();
else return yup.string().notRequired();
}),
});
but I ended up with the error I mentioned.
2
Answers
what version of
yup
are you using in your project?I had the same error with
"yup": "^1.2.0"
also in another project I am using an older version which is:
"yup": "^0.32.11"
and I used the same approach you used and worked fine without any issues.however, this should work without any errors:
I updated the schema to this and it works. They might have updated how the
.when
stuff works