TypeScript泛型限制下React高阶组件无法正确分配props问题求助
问题根因
你之前的写法报错是因为T extends ControlledInput的定义允许T是ControlledInput的子类型,例如T可以对value、onChange做更窄的类型限制,此时你在HOC内部固定传入的string类型value和接收string参数的onChange就有可能不符合T的类型要求,TS为了类型安全就会抛出错误。
正确实现
把泛型参数调整为指代「除了value、onChange之外的其余props类型」,从根源上避免类型不确定性,不需要任何类型断言:
import React, { FC } from 'react'; interface ControlledInput { value: string; onChange: (newValue: string) => void; } // 泛型P代表传入组件的自定义属性类型 function withControl<P extends object>(Elem: FC<P & ControlledInput>) { return (props: P) => { const [value, setValue] = React.useState(''); return <Elem {...props} value={value} onChange={setValue} />; }; }
使用示例
// 原有需要受控的组件 const MyInput: FC<{ label: string; disabled?: boolean } & ControlledInput> = (props) => { return ( <div> <span>{props.label}</span> <input disabled={props.disabled} value={props.value} onChange={e => props.onChange(e.target.value)} /> </div> ); }; // 封装后的组件 const ControlledMyInput = withControl(MyInput); // 调用时只需传入自定义属性,TS会自动校验类型,不需要传value/onChange <ControlledMyInput label="用户名" disabled={false} />
这个实现完全符合你的需求:
- 传入的
Elem组件必须包含value和onChange属性才能通过类型校验 - 封装后返回的新组件会自动剔除
value、onChange的传入要求 - 原有组件的其余自定义props类型会完全保留,不需要类型断言也不会丢失类型
内容的提问来源于stack exchange,提问作者Alex l.
相关产品推荐
相关产品推荐

