React+TypeScript中ProtectedRoute组件的component类型定义问题
问题根源
你当前的类型定义犯了一个关键错误:React.PureComponent | React.Component是组件实例的类型,而不是组件本身的类型。我们需要的是能被React渲染的组件类型——也就是函数组件(() => JSX.Element)或者类组件的构造函数(new (props: P) => React.Component<P>),这才是JSX语法中<Component />能识别的类型。
正确的类型定义
React已经内置了一个完美覆盖这种需求的类型:React.ComponentType。它会自动兼容函数组件、类组件(包括PureComponent),甚至是高阶组件返回的组件。修改你的Props接口如下:
import React from 'react'; export interface Props { isAuthenticated: boolean; // 使用ComponentType,涵盖所有可渲染的React组件类型 component: React.ComponentType; exact?: boolean; path: string; }
如果你的组件需要接收路由相关的props(比如location、match),还可以给ComponentType传入泛型参数,让类型检查更严谨:
import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; export interface Props { isAuthenticated: boolean; // 指定组件需要接收路由props component: React.ComponentType<RouteComponentProps>; exact?: boolean; path: string; }
修正后的组件代码
你的组件逻辑本身是没问题的,修正类型定义后,之前的TS2604错误就会消失:
import React from 'react'; import { Redirect, Route, RouteComponentProps } from 'react-router-dom'; import { ROUTES } from '../../constants/routes'; import { Props } from './ProtectedRoute.types'; const ProtectedRoute = (props: Props) => { const { isAuthenticated, component: Component, ...rest } = props; return ( <Route {...rest} children={(routeProps: RouteComponentProps) => !isAuthenticated ? ( <Redirect to={{ pathname: ROUTES.login, state: { from: routeProps.location } }} /> ) : ( <Component {...routeProps} /> ) } /> ); }; export default ProtectedRoute;
为什么这样能解决问题?
React.ComponentType是React专门为“可渲染组件”设计的类型别名,它包含了两种核心组件类型:- 函数组件:
(props: P) => React.ReactElement | null - 类组件:
new (props: P) => React.Component<P, any>
- 函数组件:
- 这样无论是传入你的
PlaceholderComponent(函数组件)还是Login(类组件),类型都会完全匹配,直接解决了第二个2322类型不兼容错误。
内容的提问来源于stack exchange,提问作者Miha Šušteršič
相关产品推荐
相关产品推荐

