I have a higher order component (HOC) that I use for auth purposes. I am converting this to a TypeScript friendly component. This is what I currently have:
import { NextPage } from 'next';
import { useAccount } from 'wagmi';
import { useAppSelector } from '../../hooks';
import EmptyState from '../EmptyState/EmptyState';
const withAuth = Component => {
const AuthenticatedComponent: NextPage = () => {
const currUser = useAppSelector(state => state.auth);
const { isConnected } = useAccount();
{
return currUser.address && isConnected ? <Component /> : <EmptyState />;
}
};
return AuthenticatedComponent;
};
export default withAuth;
And how I'd normally call it:
const Proposal: NextPage<{ proposalTags: ProposalTag[] }> = ({ proposalTags }) => { /** code here **/}
export default withAuth(Proposal);
The problem I'm having is the linter is complaining `Parameter 'Component' implicitly has an 'any' type.
I am not entirely sure how to type withAuth
in this case for the Component
argument.
I want to be able to pass it an instance of NextPage
, which may or may not contain an assortment of props of different types of their own as you can see an example of my Proposal
page above.
CodePudding user response:
You can use a generic to infer the prop types, then in the new component, pass those props to the component:
import { ComponentType } from "react";
function withAuth<P>(Component: ComponentType<P>) {
const AuthenticatedComponent: NextPage<P & JSX.IntrinsicAttributes> = (props) => {
const currUser = useAppSelector(state => state.auth);
const { isConnected } = useAccount();
{
return currUser.address && isConnected ? <Component {...props} /> : <EmptyState />;
}
};
return AuthenticatedComponent;
};
We need JSX.IntrinsicAttributes
in case the component is a "built-in" like div
, p
, etc.