You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm building a dynamic form component in TypeScript with react-hook-form that can render different types of fields (e.g., text fields, switches, checkboxes) based on a configuration array passed as props. I want the component to accept default values for these fields and display them accordingly.
Here's my code:
import{Controller,SubmitHandler,useForm}from"react-hook-form"import{Button,Stack,TextField}from"@mui/material"import{ComponentProps}from"react"importSwitchRoundLabeledfrom"./components/SwitchRoundLabeled"importCheckboxWithLabelfrom"./components/CheckboxWithLabel"// Common types for different field typestypeFormCommonFieldProps={fieldName: string}typeFormTextFieldProps={type: "textField";textFieldProps: ComponentProps<typeofTextField>}&FormCommonFieldPropstypeFormSwitchFieldProps=ComponentProps<typeofSwitchRoundLabeled>&{type: "switch";checked?: boolean}&FormCommonFieldPropstypeFormCheckboxFieldProps=ComponentProps<typeofCheckboxWithLabel>&{type: "checkbox";checked?: boolean}&FormCommonFieldPropstypeFormFieldProps=FormTextFieldProps|FormSwitchFieldProps|FormCheckboxFieldProps// Type guardsfunctionisTextField(field: FormFieldProps): field is FormTextFieldProps{returnfield.type==="textField"}functionisSwitchField(field: FormFieldProps): field is FormSwitchFieldProps{returnfield.type==="switch"}functionisCheckboxField(field: FormFieldProps): field is FormCheckboxFieldProps{returnfield.type==="checkbox"}// Extract field names for dynamic typingtypeExtractFieldNames<TextendsFormCommonFieldProps[]>=T[number]["fieldName"]typeDefaultValuesType<TextendsFormCommonFieldProps[]>=Partial<Record<ExtractFieldNames<T>,string|boolean>>exporttypeResultFormData=Record<string,string|boolean>typeFormProps<TextendsFormFieldProps[]>={fields: TdefaultValues?: DefaultValuesType<T>onSubmit?: SubmitHandler<ResultFormData>}constForm=<constTextendsFormFieldProps[]>({ fields, defaultValues, onSubmit }: FormProps<T>)=>{const{ handleSubmit, control }=useForm<ResultFormData>({
defaultValues,// (1)})return(<formonSubmit={onSubmit&&handleSubmit(onSubmit)}><Stackgap={2}sx={{color: "text.primary"}}>{fields.map((fieldData)=>{return(<Controllerkey={fieldData.fieldName}name={fieldData.fieldName}control={control}render={({field})=>{if(isTextField(fieldData)){return<TextField{...field}{...fieldData.textFieldProps}/>}if(isSwitchField(fieldData)){return<SwitchRoundLabeled{...fieldData}switchProps={{checked: !!field.value, ...field}}/>
}if(isCheckboxField(fieldData)){return<CheckboxWithLabel{...fieldData} checkboxProps={{checked: !!field.value, ...field}}/>
}return<></>
}}/>
)})}<Buttontype="submit"variant="contained"color="primary">OK</Button></Stack></form>)}exportdefaultForm
I’m encountering an issue at line (1) with the defaultValues prop. If I remove the explicit typing for ResultFormData, TypeScript shows the following error:
Type Partial<Record<ExtractFieldNames<T>, string | boolean>> is not assignable to type AsyncDefaultValues<Partial<Record<ExtractFieldNames<T>, string | boolean>>> | DefaultValues<Partial<Record<ExtractFieldNames<T>, string | boolean>>> | undefined
It seems like TypeScript cannot correctly infer the type of defaultValues. When ResultFormData is explicitly provided, everything works fine, but I would like this component to be flexible with any field configurations passed in.
Question:
Am I misunderstanding something about how defaultValues typing should work in react-hook-form?
Is this a limitation or bug in react-hook-form’s type inference for useForm?
Any suggestions on how to make this work while keeping the codebase flexible for different field configurations?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hello!
I'm building a dynamic form component in TypeScript with
react-hook-form
that can render different types of fields (e.g., text fields, switches, checkboxes) based on a configuration array passed as props. I want the component to accept default values for these fields and display them accordingly.Here's my code:
I’m encountering an issue at line
(1)
with thedefaultValues
prop. If I remove the explicit typing forResultFormData
, TypeScript shows the following error:It seems like TypeScript cannot correctly infer the type of
defaultValues
. WhenResultFormData
is explicitly provided, everything works fine, but I would like this component to be flexible with any field configurations passed in.Question:
defaultValues
typing should work inreact-hook-form
?react-hook-form
’s type inference foruseForm
?Thanks in advance!
Beta Was this translation helpful? Give feedback.
All reactions