如何在HOC中为包裹的React组件注入Prop Types
React HOC自动注入WindowSize类型的解决方案
问题背景
现有如下监听窗口尺寸的HOC:
import React, {useEffect, useState} from 'react' interface WindowSize { width: number, height: number } export function WithWindowSize <T>(Component: React.ComponentType<T>) { return function WithComponent(props: T) { const [windowSize, setWindowSize] = useState({} as WindowSize) useEffect(() => { ... }, []) return <Component {...props} windowSize={windowSize}/> } } export default WithWindowSize;
使用该HOC时尝试手动合并类型,出现报错:
interface FooProps { headline: string, value: string | number, } // 此处存在拼写错误:FoooProps → FooProps const Foo = ({headline, value, windowSize}: FooProps & WindowSize) => { return ... } export default WithWindowSize(Foo);
报错信息:
类型“FooProps & WindowSize”上不存在属性“windowSize”。
需求:希望在HOC内部实现WindowSize类型的自动注入,避免每次使用时手动处理类型合并。
解决方案
问题核心在于HOC的泛型定义逻辑错误,需要调整泛型约束,让TypeScript明确:传入的组件需要包含WindowSize类型的Props,而返回的组件仅需接收用户自定义的Props(WindowSize由HOC自动注入)。
修改后的HOC代码
import React, {useEffect, useState} from 'react' interface WindowSize { width: number, height: number } // 泛型调整:传入组件接收「用户自定义Props(T) + WindowSize」,返回组件仅接收T export function WithWindowSize<T>(Component: React.ComponentType<T & WindowSize>) { return function WithComponent(props: T) { // 初始化窗口尺寸,避免空对象类型警告 const [windowSize, setWindowSize] = useState<WindowSize>({ width: window.innerWidth, height: window.innerHeight }); useEffect(() => { // 实现窗口resize监听逻辑 const handleResize = () => { setWindowSize({ width: window.innerWidth, height: window.innerHeight }); }; window.addEventListener('resize', handleResize); // 组件卸载时清理监听 return () => window.removeEventListener('resize', handleResize); }, []); return <Component {...props} windowSize={windowSize}/> } } export default WithWindowSize;
使用方式(无需手动合并类型)
interface FooProps { headline: string, value: string | number, } // 直接解构windowSize,类型由HOC自动注入,无需手动声明WindowSize const Foo = ({headline, value, windowSize}: FooProps) => { return ( <div> <h1>{headline}</h1> <p>当前值: {value}</p> <p>窗口宽度: {windowSize.width}</p> <p>窗口高度: {windowSize.height}</p> </div> ); } export default WithWindowSize(Foo);
关键说明
- 调整泛型约束后,TypeScript会自动识别被HOC包裹的组件可直接使用
windowSize属性,无需在组件Props类型中手动合并WindowSize - 修复了原代码中
useState初始化空对象的类型不安全问题,直接用当前窗口尺寸初始化状态 - 补充了完整的窗口resize监听与清理逻辑,保证功能完整性与内存安全
内容的提问来源于stack exchange,提问作者four-eyes
相关产品推荐
相关产品推荐

