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

通过React高阶组件透传children的正确TypeScript类型如何定义?

正确实现方案

核心逻辑是不要手动给注入属性InjectedProps加children声明,完全通过泛型推导原组件的props类型,实现children属性的自动透传:原组件声明了接受children则包裹后的组件支持传入,原组件未声明则禁止传入,保证类型安全。

完整代码

import type { ComponentType } from 'react';

// 注入属性不要加children
interface InjectedProps {
  someProp?: number;
}

const myHoc = <P,>(Component: ComponentType<P>) => {
  // 包裹后组件的props = 原组件所有props + HOC自身的注入属性
  return (props: P & InjectedProps) => {
    // 剥离HOC自己消费的属性,剩余属性透传给原组件
    const { someProp, ...componentProps } = props;
    return <Component {...componentProps} />;
  };
};

// 测试用例1:原组件接受children
const MyComponent = (props: { children?: React.ReactNode }) => {
  return <div>{props.children}</div>;
};
const WrappedComponent = myHoc(MyComponent);
// 合法,不会报错
<WrappedComponent>
  <h1>Hello</h1>
  <h2>World</h2>
</WrappedComponent>

// 测试用例2:原组件不接受children
const MyComponentNoChildren = (props: { id: string }) => {
  return <div id={props.id} />;
};
const WrappedNoChildren = myHoc(MyComponentNoChildren);
// 传入children会触发类型报错,符合预期
// <WrappedNoChildren id="test"><span>非法内容</span></WrappedNoChildren>

原错误写法的问题

你之前给InjectedProps手动加children的方案,相当于强制给所有被HOC包裹的组件都加上了可选的children属性,跳过了原组件的props校验,破坏了类型安全。

原理说明

  1. 泛型P会自动推导为传入HOC的原组件的props类型,包含原组件声明的children(如果有的话)
  2. 包裹后组件的props定义为P & InjectedProps,自动继承原组件的所有props约束,不需要手动声明children
  3. 去掉了多余的as P类型断言,避免打断TS的类型推导流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 21:09:00