使用react-select时forwardRef触发TypeScript类型不兼容错误
问题
在使用react-select的Select组件时,自定义SelectInput组件中使用forwardRef遇到了TypeScript错误。
错误提示:
Type 'ForwardedRef<HTMLInputElement>' is not assignable to type 'LegacyRef<Select<Option, false, GroupBase<Option>>> | undefined'.
代码示例:
import Select from "react-select"; export const SelectInput = forwardRef<HTMLInputElement, SelectInputProps>( (props, ref) =>{ ... return( <div> <Select key="random-key" ref={ref} .... /> </div> ) } )
此前将相同类型和forwardRef用于原生input元素时一切正常,但此处报错,完整错误日志如下:
Type 'ForwardedRef<HTMLInputElement>' is not assignable to type 'LegacyRef<Select<Option, false, GroupBase<Option>>> | undefined'. Type '(instance: HTMLInputElement | null) => void' is not assignable to type 'LegacyRef<Select<Option, false, GroupBase<Option>>> | undefined'. Type '(instance: HTMLInputElement | null) => void' is not assignable to type '(instance: Select<Option, false, GroupBase<Option>> | null) => void | (() => VoidOrUndefinedOnly)'. Types of parameters 'instance' and 'instance' are incompatible. Type 'Select<Option, false, GroupBase<Option>> | null' is not assignable to type 'HTMLInputElement | null'. Type 'Select<Option, false, GroupBase<Option>>' is missing the following properties from type 'HTMLInputElement': accept, align, alt, autocomplete, and 352 more.
解决方案
问题核心:你给forwardRef指定的泛型类型是HTMLInputElement,但react-select的Select组件接收的ref需要的是自身组件实例类型,而非原生input元素类型,类型不匹配导致报错。
情况1:需要获取Select组件实例的ref
直接修正forwardRef的泛型参数为react-select提供的组件实例类型:
import Select, { SelectInstance } from "react-select"; // 替换HTMLInputElement为SelectInstance<Option>,Option是你的选项类型 export const SelectInput = forwardRef<SelectInstance<Option>, SelectInputProps>( (props, ref) => { // ... 你的业务逻辑 return ( <div> <Select key="random-key" ref={ref} // ... 其他Select组件props /> </div> ); } );
情况2:需要获取Select内部原生input元素的ref
如果实际需要的是组件内部的原生input,不能直接把外层ref传给Select,需要自定义Input组件来转发ref:
import Select, { Components, InputProps } from "react-select"; // 自定义Input组件,将ref转发到原生input const CustomInput = forwardRef<HTMLInputElement, InputProps<Option>>( (props, ref) => { return <Components.Input {...props} ref={ref} />; } ); export const SelectInput = forwardRef<HTMLInputElement, SelectInputProps>( (props, ref) => { // ... 你的业务逻辑 return ( <div> <Select key="random-key" components={{ Input: CustomInput }} // 替换默认Input组件 // ... 其他Select组件props /> </div> ); } );
内容的提问来源于stack exchange,提问作者Opera man
相关产品推荐
相关产品推荐

