You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-hook-form中select使用readOnly报TypeScript错误如何解决?

报错原因

该错误和react-hook-form无关,本质是原生HTML的<select>标签本身不支持readOnly属性,只有<input>、<textarea>等输入类元素才有该属性。因此TypeScript的内置类型定义中,SelectHTMLAttributes不存在readOnly字段,才会触发类型不匹配报错。

可行解决方案

方案1:CSS+属性拦截实现只读效果(最推荐)

完全符合原生表单规则,不会触发类型报错,同时可保证表单提交时字段值正常被收集:

<select
  id={props.field_id}
  {...register(...)}
  defaultValue={...}
  onChange={props.disabled ? () => {} : yourOriginalOnChangeHandler}
  tabIndex={props.disabled ? -1 : 0}
  style={props.disabled ? { pointerEvents: 'none', opacity: 0.6 } : {}}
>
  <option>{/* 选项内容 */}</option>
  {renderList(...)}
</select>

逻辑说明:

  • pointerEvents: none 直接阻断所有鼠标交互,用户无法点击展开下拉框
  • tabIndex=-1 阻止用户通过Tab键聚焦到选择框,避免用键盘快捷键修改选项
  • disabled状态下清空onChange逻辑,做双重保险
  • 透明度调低给用户明确的不可操作提示

方案2:使用react-hook-form内置的disabled配置

react-hook-form的register方法自带disabled参数,和原生disabled属性不同,该配置默认不会把字段从提交数据中剔除:

<select
  id={props.field_id}
  {...register('yourFieldName', { disabled: props.disabled })}
  defaultValue={...}
>
  {/* 选项内容 */}
</select>

如果你的表单全局配置开启了shouldUnregister: true,只需要在提交时调用getValues('yourFieldName')主动获取该字段值,补入提交给API的参数中即可。

方案3:类型层面绕过(仅临时兼容用,不推荐)

如果必须保留readOnly属性写法,可通过类型断言跳过TypeScript检查:

<select
  {...register(...)}
  {...({ readOnly: props.disabled } as React.HTMLProps<HTMLSelectElement>)}
>

也可在全局类型定义文件中扩展SelectHTMLAttributes接口,添加readOnly属性声明,解决全项目的同类报错。

内容的提问来源于stack exchange,提问作者Chrissisbeast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 04:57:03