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

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.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 06:57:01