How to write a generic type that includes all props from one generic type that are not in another?
I'm trying to write a generic HOC that takes a component with props TProps and a type TEntry defining an object structure. I want the HOC to return a component which will call a hook to get an object instance of type TEntry from a particular source (in this case a CMS). This resulting component should only require the consumer to provide the props that are not filled in by that CMS data.
I thought that Exclude<TProps, TEntry> would work for this, but I'm still ending up with a component that requires all of TProps. Here's what I've tried (this is rather stripped down for simplicity):
const withCmsData = <
TEntry,
TProps,
>(
Component: (props: TProps) => (JSX.Element | null)
) => {
return (props: Exclude<TProps, TEntry>) => {
const { entry } = useCmsEntries<TEntry>();
return <Component {...entry} {...props} />;
};
};
...and here's an example of how you'd use it to create a new component with fewer props:
type ArticlePageProps = {
title: string;
subTitle: string;
date: string;
}
const ArticlePage = ({ title, subTitle, date }: ArticlePageProps) => {
return (
<>
<h1>{title}</h1>
<div>{subTitle}</div>
<div>{date}</div>
</>
);
}
type ArticleFromCmsProps = {
title: string;
subTitle: string;
}
/*
This creates a new component that now only requires a data prop,
which is the one prop from ArticlePageProps that is
not provided by ArticleFromCmsProps:
*/
const MyPageWrapper = withCmsData<ArticlePageProps, ArticleFromCmsProps>(ArticlePage);
const render = () => {
const data = new Date();
<MyPageWrapper date={date} />
}
Is there a way to get the generic HOC I want? One that returns a component only requiring props not provided by a call to the CMS?
Comments
Post a Comment