How do I write generic higher order component that inject generic props?

55 Views Asked by At

I am trying to create an hoc which infers query params from next router, however I am unable to use it properly when I have to chain my components.

type Params<Q extends string> = Record<Q, string>;

function withQueryParam<Q extends string, P extends Params<Q>>(
  queryParamName: Q
) {
  return (Component: NextPage<P>) => {
    const displayName = Component.displayName || Component.name || "Component";

    const ComponentWrapped = (props:Omit<P, keyof Params<Q>>) => {
      const router = useRouter();
      const queryParamValue = router.query[queryParamName];

      if (!queryParamValue) {
        return <p>{"Loading Params"}</p>;
      }

      if (typeof queryParamValue !== "string") {
        return <p>{"Params"}</p>;
      }

      return (
        <Component
          {...(props as P)}
          {...{ [queryParamName]: queryParamValue }}
        />
      );
    };

    ComponentWrapped.displayName = `withQueryParam(${displayName})`;
    return ComponentWrapped;
  };
}

Now I do have type inference, if I do as follows

const AppointmentPage = withQueryParam("teamId")(({teamId}) => {
  return <div></div>
});

but I am just unable to get query params of outer hoc, if I do some chaining as follows

//[ERROR]: teamId is not defined
const AppointmentPage = withQueryParam("teamId")(withQueryParam('appointmentId')(({appointmentId,teamId}) => {
  return <div></div>
}));

0

There are 0 best solutions below