// 1. cant use React.ComponentType else we loose generics
const withStuff = <TProps,>(Component: (props: TProps) => React.ReactNode) => {
const stuff = useStuff();
return (props: Omit<TProps, 'stuff'>) => {
// 2. gotta use `as` here, I know it's annoying
return <Component {...(props as TProps)} stuff={stuff} />;
};
};
type MyComponentProps<T> = {
stuff: Stuff;
items: T[];
defaultItem: T;
};
const MyComponent = <T extends React.ReactNode>(props: MyComponentProps<T>) => {
return (
<div>
{props.items.map((item) => (
<div>{item}</div>
))}
</div>
);
};
const StuffedComponent = withStuff(MyComponent);
<>
<StuffedComponent items={[1, 2, 3]} defaultItem={1} />
{/* 3. defaultItem is inferred to be 1 | 2 | 3 */}
</>;
This is the same trick we used to get nicer forwardRef
here.
Return home to Smooth Unfolding