通过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校验,破坏了类型安全。
原理说明
- 泛型
P会自动推导为传入HOC的原组件的props类型,包含原组件声明的children(如果有的话) - 包裹后组件的props定义为
P & InjectedProps,自动继承原组件的所有props约束,不需要手动声明children - 去掉了多余的
as P类型断言,避免打断TS的类型推导流程
内容的提问来源于stack exchange,提问作者Fern
相关产品推荐
相关产品推荐

