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

如何为React.Children.map添加未暴露给消费者的内部props并正确声明TS类型?

解决方案

核心思路是拆分Inner组件的属性为「外部传入的公开属性」和「Wrapper注入的私有属性」,对外仅暴露包含公开属性的组件类型,内部通过安全类型断言获取注入属性,完全不会将内部属性暴露给使用者。

步骤1:拆分属性类型

// Inner 对外公开的属性,使用者仅需传入该部分内容
interface InnerPublicProps {
  title: string;
  caption: string;
}

// Inner 内部使用的注入属性,由Wrapper自动传递,完全不对外暴露
interface InnerInjectedProps {
  onChange: (e: React.SyntheticEvent) => void;
  value: number | null;
  selected: boolean;
}

// Inner 内部实际用到的完整属性类型
type InnerFullProps = InnerPublicProps & InnerInjectedProps;

步骤2:调整Inner组件声明

对外导出的Inner组件类型仅声明公开属性,内部通过类型断言获取注入属性:

// 对外暴露的组件类型仅要求传入公开属性
export const Inner: React.FC<InnerPublicProps> = (props) => {
  // 内部断言为完整属性类型,该操作是安全的:只有被Wrapper包裹的Inner才会被渲染,Wrapper保证注入全部私有属性
  const { title, caption, onChange, value, selected } = props as unknown as InnerFullProps;

  return (
    <ThirdPartyComponent onChange={onChange} value={value} selected={selected}>
      <h1>{title}</h1>
      <h5>{caption}</h5>
    </ThirdPartyComponent>
  );
};

步骤3:(可选)优化Wrapper类型,替换any

const Wrapper: React.FC<{
  value: number | null;
  handleChange: (index: number) => (e: React.SyntheticEvent, newValue: number | null) => void;
}> = ({ value, handleChange, children }) => {
  return React.Children.map(children, (child, index) => {
    if (!child || !React.isValidElement(child)) {
      return null;
    }
    return React.cloneElement(child, {
      onChange: handleChange(index),
      value,
      selected: value === index,
      ...child.props,
    });
  });
};

调整后,使用者调用<Inner />时,TS只会提示需要传入title和caption两个属性,onChange、value、selected三个内部属性完全不会对外暴露,也不需要设置为可选属性,完全符合要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:54:02