Pexidious
Pexidious
TTCTheo's Typesafe Cult
Created by Pexidious on 11/16/2023 in #questions
Need help with inferring a higher-order component
Hi! I'm trying to create a higher-order component in React that enhances a given component with an additional type. This additional type is used internally of the HOC as it's the return type of the data that's being fetched. The wrapped component will receive the props from the extra data and the rest of the props that the component accepts. To keep the example simple, I've simplified the HOC a bit and it looks like this:
type Props = {
applicationId: string;
};

export const withApplicationData = <
TData extends object,
TProps extends TData
>(
Component: ComponentType<TProps>
) => {
return function WithApplicationData({
applicationId,
...props
}: Props & Omit<TProps, keyof TData>) {
const data = getDataForApplication<TData>(applicationId);

if (!data) {
return null;
}

return <Component {...(props as TProps)} {...data} />;
};
};
type Props = {
applicationId: string;
};

export const withApplicationData = <
TData extends object,
TProps extends TData
>(
Component: ComponentType<TProps>
) => {
return function WithApplicationData({
applicationId,
...props
}: Props & Omit<TProps, keyof TData>) {
const data = getDataForApplication<TData>(applicationId);

if (!data) {
return null;
}

return <Component {...(props as TProps)} {...data} />;
};
};
I would like to use the HOC like this:
type ApplicationData = {
foo: string;
};

type Props = {
bar: string;
};

function MyComponent({ foo, bar }: ExtraData & Props) {
return <div>MyComponent</div>
};

const MyComponentWithData = withApplicationData<ApplicationData>(MyComponent);
type ApplicationData = {
foo: string;
};

type Props = {
bar: string;
};

function MyComponent({ foo, bar }: ExtraData & Props) {
return <div>MyComponent</div>
};

const MyComponentWithData = withApplicationData<ApplicationData>(MyComponent);
However, this doesn't work as the second type helper for withApplicationData doesn't get inferred correctly and it's currently mandatory, meaning I have to use the following code to make it work:
const MyComponentWithData = withApplicationData<ApplicationData, ApplicationData & Props>(MyComponent);
const MyComponentWithData = withApplicationData<ApplicationData, ApplicationData & Props>(MyComponent);
This is redundant as the props can be inferred from the passed component to the HOC. Is there a way to infer this type correctly? So that I don't have to pass a second type argument each time I want to use this HOC?
5 replies
TTCTheo's Typesafe Cult
Created by Pexidious on 10/19/2022 in #questions
Dynamically rendering a component using an object
3 replies