CaribouCode
CaribouCode

Reputation: 14398

Correct types for FunctionComponent HOC

I have a HOC like so:

utils/withGlobalSettings.tsx

interface Props {
  globalSettings: {
    ...
  };
}

export default (Component: React.ComponentType<Props>) => () => {
  const locale = useContext(localeContext);
  const { data } = useQuery(dataGlobalSettingsCollection);
  return <Component globalSettings={globalSettings} />;
};

I used this on several simple components and it works great. The problem is when I use it on a component that expects it's own props too, like so:

components/Products.tsx

interface Props {
  globalSettings: {
    ...
  };
  products: {
    ...
  }[];
}

const Products: React.FunctionComponent<Props> = ({
  globalSettings,
  products,
}) => (
  ...
);

export default withGlobalSettings(Products);

In this case, typescript complains:

Property 'products' is missing in type 'PropsWithChildren' but required in type 'Props'.

I believe this is because I haven't set up the HOC correctly to pass through props other than the globalSettings one generated inside the prop. How is this achieved with function component HOCs in typescript?

Upvotes: 0

Views: 236

Answers (1)

Kaca992
Kaca992

Reputation: 2267

You need something like this:

const wrapper = <T extends Props>(Component: React.ComponentType<T>) => (ownProps: Omit<T, keyof Props>) => {
  const globalSettings = { test: 2 };
  const props = { globalSettings, ...ownProps };
  return <Component {...props as T} />;
};

And you would use it like this:

const NewProduct = wrapper(Product);
<NewProduct products={...} />

Upvotes: 2

Related Questions