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.
CodePudding user response:
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