在自定义控制器组件中使用传递给useForm的泛型



使用react-hook-form,我正在尝试制作一个自定义的ControlledTextField组件来使用我的组件库。按照userForm的打字脚本用法,我可以创建这样的表单

export interface AuthenticationData {
email: string,
password: string
}
const { handleSubmit, control } = useForm<AuthenticationData>({
resolver: yupResolver(LoginSchema),
})

然后我创建我的自定义ControlledTextField组件

import { FormControl, Input } from "native-base"
import { Controller, UseControllerProps } from "react-hook-form"
interface ControlledTextFieldProps extends UseControllerProps {
label: string
}
const ControlledTextField = ({ control, name, label, ...props }: ControlledTextFieldProps) => {
return (
<Controller
control={control}
name={name}
render={({
fieldState: { invalid, error },
field: { onChange, onBlur, value },
}) => (
<FormControl mb="5" isInvalid={invalid}>
<FormControl.Label>{label}</FormControl.Label>
<Input
onBlur={onBlur}
onChange={onChange}
value={value}
/>
<FormControl.ErrorMessage>
{error?.message ?? ""}
</FormControl.ErrorMessage>
</FormControl>
)}
/>
)
}
export default ControlledTextField

当试图实现时,我得到了这个错误

Type 'Control<AuthenticationData, any>' is not assignable to type 'Control<FieldValues, any>'.
The types of '_options.resolver' are incompatible between these types.
Type 'Resolver<AuthenticationData, any> | undefined' is not assignable to type 'Resolver<FieldValues, any> | undefined'.
Type 'Resolver<AuthenticationData, any>' is not assignable to type 'Resolver<FieldValues, any>

实现看起来是这样的。。。

<ControlledTextField
name="email"
label="Email"
control={control}
/>

我也遇到过这个问题。我得到的解决方案是通过一个泛型传递Control属性,该泛型将FieldValues类型扩展到ControlledTextField组件。从那时起,您应该能够获得具有正确推断类型的各种变量。

组件实现应该看起来像这样:

import { FormControl, Input } from "native-base"
import { Controller, UseControllerProps, Control, FieldPath, FieldValues } from "react-hook-form"
interface ControlledTextFieldProps<T extends FieldValues> extends UseControllerProps {
label: string;
control: Control<T>;
name: FieldPath<T>;
defaultValue: T[keyof T];
}
const ControlledTextField = ({ control, name, label, defaultValue, ...props }: ControlledTextFieldProps) => {
return (
<Controller
control={control}
name={name}
render={({
fieldState: { invalid, error },
field: { onChange, onBlur, value },
}) => (
<FormControl mb="5" isInvalid={invalid}>
<FormControl.Label>{label}</FormControl.Label>
<Input
onBlur={onBlur}
onChange={onChange}
value={value}
/>
<FormControl.ErrorMessage>
{error?.message ?? ""}
</FormControl.ErrorMessage>
</FormControl>
)}
/>
)
}
export default ControlledTextField

然后,当您实现组件时:

<ControlledTextField
name="email"
label="Email"
control={control}
defaultValue=""
/>

最新更新