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?
Solution:
Asked this question in a different Discord group and found out that this can only be done by adding an extra curried function. When the following GitHub issue gets resolved, which has been open since 2018, the second type helper can probably be inferred: https://github.com/microsoft/TypeScript/issues/26242...
GitHub
Proposal: Partial Type Argument Inference · Issue #26242 · microsof...
After exploring the concept in #23696, we've come to the conclusion that implicitly making type arguments available by name would unnecessarily expose previously unobservable implementation det...
Jump to solution
2 Replies
Solution
Pexidious
Pexidious12mo ago
Asked this question in a different Discord group and found out that this can only be done by adding an extra curried function. When the following GitHub issue gets resolved, which has been open since 2018, the second type helper can probably be inferred: https://github.com/microsoft/TypeScript/issues/26242
GitHub
Proposal: Partial Type Argument Inference · Issue #26242 · microsof...
After exploring the concept in #23696, we've come to the conclusion that implicitly making type arguments available by name would unnecessarily expose previously unobservable implementation det...
Want results from more Discord servers?
Add your server