如何编写可注入泛型Props的泛型HOC?解决链式调用类型缺失问题
解决Next.js HOC链式调用时查询参数类型推断失效问题
问题根源
你当前的withQueryParam泛型约束逻辑搞反了:原本是想让HOC注入Q参数给组件,但泛型P extends Params<Q>强制要求组件的props必须已经包含Q。链式调用时,内层组件的props声明了appointmentId和teamId,内层HOC处理后返回的组件props会移除appointmentId,此时外层HOC要求传入的组件props必须包含teamId,但内层返回的组件props里没有该字段,导致类型冲突,外层注入的teamId无法被类型系统识别。
修复后的实现
调整泛型逻辑,让HOC接受需要Q参数的组件,返回不需要传入Q参数的组件,同时正确合并类型:
import { NextPage, useRouter } from 'next'; type QueryParam<Q extends string> = Record<Q, string>; function withQueryParam<Q extends string>(queryParamName: Q) { return <P extends QueryParam<Q>>(Component: NextPage<P>) => { const displayName = Component.displayName || Component.name || 'Component'; const ComponentWrapped = (props: Omit<P, Q>) => { const router = useRouter(); const queryParamValue = router.query[queryParamName]; if (!queryParamValue) { return <p>Loading Params</p>; } if (typeof queryParamValue !== 'string') { return <p>Invalid Param Format</p>; } return <Component {...props} {...{ [queryParamName]: queryParamValue } as QueryParam<Q>} />; }; ComponentWrapped.displayName = `withQueryParam(${displayName})`; return ComponentWrapped; }; }
验证链式调用
现在链式调用时,类型推断会正确合并两个HOC注入的参数:
// 类型推断正常,teamId和appointmentId都能被识别 const AppointmentPage = withQueryParam('teamId')( withQueryParam('appointmentId')(({ appointmentId, teamId }) => { return <div>Team: {teamId}, Appointment: {appointmentId}</div>; }) );
逻辑说明
- 泛型
Q指定要注入的查询参数名,P是组件需要的完整props类型(必须包含Q) - 包装后的组件只需要接收
Omit<P, Q>类型的props,即组件原本需要的props去掉查询参数部分 - 从Router中获取参数后,将其与传入的props合并,传递给原始组件,类型系统会正确识别注入的参数
内容的提问来源于stack exchange,提问作者ahmad sheraz
相关产品推荐
相关产品推荐

