react-hook-form Control类型不匹配 保留自定义类型解决方案
类型报错修复方案
报错根源
报错本质是自定义Input组件使用的ControllerProps默认绑定了react-hook-form内置的FieldValues作为表单类型泛型,和你在页面中通过useForm<IOtp>生成的Control<IOtp>泛型参数不匹配,不需要移除自定义表单类型定义,只要给封装的Input组件增加泛型支持即可解决。
修复步骤
- 改造Input组件为泛型组件,支持接收外部传入的表单类型参数,让组件可以匹配任意表单结构的control实例
- 拆分Controller专属属性和TextField属性,避免将react-hook-form的内部属性透传给MUI TextField触发无效DOM属性警告
修复后的Input组件代码如下:
import TextField from "@mui/material/TextField" import type { TextFieldProps } from "@mui/material/TextField" import { Controller, type ControllerProps, type FieldPath, type FieldValues } from "react-hook-form" function Input< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues> >(props: Omit<ControllerProps<TFieldValues, TName>, "render"> & TextFieldProps) { // 拆分Controller专属属性和TextField接收的属性 const { name, control, rules, shouldUnregister, defaultValue, disabled, ...textFieldProps } = props return ( <Controller name={name} control={control} rules={rules} shouldUnregister={shouldUnregister} defaultValue={defaultValue} disabled={disabled} render={({ field }) => ( <TextField {...textFieldProps} {...field} /> )} /> ) } export default Input
修复效果
改造完成后,在OTP页面使用Input组件时:
- 不会再出现
Control类型不兼容的报错 - TypeScript会自动根据传入的
control实例推导表单类型,name属性会自动提示当前表单下的合法字段,传错字段名会直接触发类型校验 - 自定义的
IOtp类型定义可以完整保留,表单提交、字段值校验都会获得完整的类型提示
内容的提问来源于stack exchange,提问作者aksal
相关产品推荐
相关产品推荐

