TypeScript与React 如何定义组件入参以兼容函数组件与类组件
问题本质
你之前在IPublicRouteWrapperProps中把component属性定义为typeof Component,这个类型的覆盖范围非常窄——它仅匹配类组件的构造函数签名,要求传入值必须支持通过new操作符生成组件实例。而函数组件本质是返回JSX的普通纯函数,不具备构造函数特征,自然会触发类型不兼容报错。
兼容两类组件的正确实现方式
不需要自己手写复杂的联合类型,直接使用React官方内置的通用组件类型即可实现全场景兼容:
- 移除原有
component: typeof Component的类型定义 - 将
component的类型替换为React.ComponentType
这个类型是React官方定义的联合类型,本身就完整覆盖了两类合法React组件的类型范围:- 无状态/有状态函数组件的类型签名
React.FunctionComponent - 类组件的构造函数类型
typeof React.Component
- 无状态/有状态函数组件的类型签名
调整后的接口示例
interface IPublicRouteWrapperProps { // 可同时兼容传入函数组件、类组件作为页面参数 component: React.ComponentType; // 其他路由相关的自定义属性正常定义即可 requireAuth?: boolean; }
可选的类型优化方案
如果需要更精细的类型约束,可以根据实际场景给ComponentType传入对应的泛型参数:
- 所有传入的页面组件不需要接收任何自定义props时,直接用不带泛型的
React.ComponentType即可,完全适配你当前的HomePage、ReceiptPage两个组件 - 路由包装组件需要给内部渲染的页面传入路由相关props(比如
match、location、history等)时,可以将对应的props类型作为泛型传入:import type { RouteComponentProps } from 'react-router-dom'; interface IPublicRouteWrapperProps { component: React.ComponentType<RouteComponentProps>; }
常见避坑提醒:不要将
component属性定义为React.ReactNode,这个类型是用来描述组件渲染输出的视图内容的,不是用来描述可被调用的组件本身的类型,会导致后续在包装组件内部渲染传入页面时出现新的类型错误。
内容的提问来源于stack exchange,提问作者Grant Birchmeier
相关产品推荐
相关产品推荐

