I have the following code where I'm rendering a component or redirecting the user based on auth state. I'm having trouble understanding what the component prop type should be set to in the interface I've declared:
import { useState } from 'react';
import { Redirect, Route } from 'react-router-dom';
import { useAuthState } from '../../../context/authenticationContext';
interface AppProps {
path: string,
isPrivate: boolean,
}
const AppRoutes = ({ component: Component, path, isPrivate, ...rest }: AppProps) => {
const authDetails = useAuthState();
...
return (
<Route
path={path}
render={props => (isPrivate && !authDetails.user) ? (
<Redirect
to={{ pathname: "/" }}
/>
) : (
<Component {...props} />
)
}
{...rest}
/>
)
}
export default AppRoutes
As you can see my interface is missing the component type. Not sure what to set it to.
If you want to type component constructor you should use import {ComponentType} from 'react'
.
So, if you want to build Component
with props from render
function, you should apply a constraint for ComponentTypeProps
.
In other words, your Component
should expect Route['render']
type of argument.
In order to get type of render
argument, you should use ComponentProps
utility, which you can import from 'react'.
COnsider this example:
type RenderProps = Parameters<NonNullable<ComponentProps<typeof Route>['render']>>[0]
Now you can use appropriate constraint:
import React, { ComponentType, ComponentProps } from 'react';
import { Route } from 'react-router-dom';
interface AppProps {
path: string,
isPrivate: boolean,
Component: ComponentType<RenderProps>
}
type RenderProps = Parameters<NonNullable<ComponentProps<typeof Route>['render']>>[0]
const AppRoutes = ({ Component, path, isPrivate, ...rest }: AppProps) => {
return (
<Route
path={path}
render={props => <Component {...props} />}
{...rest}
/>
)
}
export default AppRoutes