-
Is there a way to specify a type for the value received from useController? Currently, TypeError occurs, so I am using assertiveness, but I think it is ideal to specify the type using generics. const {field: {value}} = useController();
// Type Error
<input value={value}>
// There are no errors, but I want to avoid them
<input value={value as string}> |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
Ask more specific questions. I created a generic'TextAreaComponent'. import React, { TextareaHTMLAttributes } from 'react';
import { useController, UseControllerProps } from 'react-hook-form';
const ControlledTextarea = <T,>({
name,
rules,
shouldUnregister,
defaultValue,
control,
...props
}: UseControllerProps<T> & TextareaHTMLAttributes<HTMLTextAreaElement>) => {
const { field } = useController({
control,
name,
});
return (
<div>
<label>label</label>
<textarea {...field} {...props} value={field.value as string} />
</div>
);
};
export default ControlledTextarea;
// use
<ControlledTextarea name="description" control={control} /> I would like to avoid assertions ( Thank you for your support. |
Beta Was this translation helpful? Give feedback.
-
Check out #7246 discussion. Looks like it's related |
Beta Was this translation helpful? Give feedback.
-
I create a custom hook @nino-cast import { useController } from 'react-hook-form';
type Option = { $default?: any };
export default function useField<TValue = string>(name: string, { $default = '' }: Option = {}) {
const {
field: { ref, value, onChange },
fieldState: { error },
} = useController({ name, defaultValue: $default });
// To typecast the input value
const val: TValue = value;
return { ref, value: val, error: error?.message, setValue: onChange };
} |
Beta Was this translation helpful? Give feedback.
-
For those who still need this on V7, following seems to works nicely and it's easily reusable as a type utility: type AssertFieldValueType<TFieldValues extends FieldValues, Name extends FieldPath<TFieldValues>, K> =
FieldPathValue<TFieldValues, Name> extends K ? {} : { $: `Value of ${Name} is not compatible with the component` }
type ControllerWrapperProps<
TFieldValues extends FieldValues,
Name extends FieldPath<TFieldValues>,
Props extends { value: Value; onChange: (value: Value) => void },
Value = Props['value'],
> = {
control: Control<TFieldValues>
name: Name
} & Omit<Props, 'value' | 'onChange'> &
AssertFieldValueType<TFieldValues, Name, Value>
export const MyFieldController = <TFieldValues extends FieldValues, Name extends FieldPath<TFieldValues>>({
control,
name,
...props
}: ControllerWrapperProps<TFieldValues, Name, MyFieldProps>) => {
return (
<Controller
control={control}
name={name}
render={({ field }) => <MyField {...props} value={field.value} onChange={field.onChange} />}
/>
)
}
<MyFieldController control={control} name="wrongField" />
// Property '$' is missing in type '{ control: Control<MyFieldData, any>; name: "wrongField"; size: "small"; }' but required in type '{ $: "Value of wrongField is not compatible with the component"; }'.ts(2741)
<MyFieldController control={control} name="correctField" />
// No error |
Beta Was this translation helpful? Give feedback.
Check out #7246 discussion. Looks like it's related