Skip to content

Instantly share code, notes, and snippets.

@itsdouges
Last active January 27, 2020 19:49
Show Gist options
  • Save itsdouges/0de18176fc30c26767e2705f0f5281ef to your computer and use it in GitHub Desktop.
Save itsdouges/0de18176fc30c26767e2705f0f5281ef to your computer and use it in GitHub Desktop.
Passing default props info through a HOC using TypeScript 3.1.x
import * as React from 'react';
type Omit<T, K extends keyof any> = T extends any ? Pick<T, Exclude<keyof T, K>> : never;
type ExtractProps<TComponentOrTProps> = TComponentOrTProps extends React.ComponentType<
infer P
>
? P
: never;
interface InjectedProps {
injected: boolean;
}
export const withInjector = <
TComponent extends React.ComponentType<InjectedProps & ExtractProps<TComponent>>
>(
WrappedComponent: TComponent
) => {
type WithInjectorProps = JSX.LibraryManagedAttributes<
TComponent,
ExtractProps<TComponent>
>;
return class extends React.Component<Omit<WithInjectorProps, keyof InjectedProps>> {
static displayName = `withInjector(${WrappedComponent.displayName})`;
render() {
// Coercing this makes us able to use it as JSX.
const CoercedWrappedComponent = WrappedComponent as React.ComponentType<InjectedProps & ExtractProps<TComponent>>;
return (
// works
<CoercedWrappedComponent injected {...this.props} />
);
return (
// [ts] JSX element type 'WrappedComponent' does not have any construct or call signatures.
<WrappedComponent injected {...this.props} />
);
}
};
};
@itsdouges
Copy link
Author

Np :)

@horvathgyozo
Copy link

As I see, it doesn't work with TypeScript 3.2.2. It says for the CoercedWrappedComponent:

Type '{ injected: true; } & Readonly<{ children?: ReactNode; }> & Readonly<Omit<LibraryManagedAttributes<TComponent, ExtractProps<TComponent>>, "injected">>' is not assignable to type 'IntrinsicAttributes & InjectedProps & ExtractProps<TComponent> & { children?: ReactNode; }'.
  Type '{ injected: true; } & Readonly<{ children?: ReactNode; }> & Readonly<Omit<LibraryManagedAttributes<TComponent, ExtractProps<TComponent>>, "injected">>' is not assignable to type 'ExtractProps<TComponent>'. [2322]

@itsdouges
Copy link
Author

ah that's a shame. I guess something has changed in the latest minor version. were you able to work through it?

@bolivier
Copy link

bolivier commented Feb 1, 2019

How is this possible: <TComponent extends React.ComponentType<InjectedProps & ExtractProps<TComponent>>>?

Shouldn't TComponent not be available at ExtractProps?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment