-
Notifications
You must be signed in to change notification settings - Fork 786
Component loses typings with HOC #379
Comments
Sure, this sounds reasonable if you can make it work. |
Cool, I'll take a look and open a PR |
I've got it working with Stateless Components and regular classes, but it fails when using a decorator. Been through a bunch of variations and can't seem to make it work properly. export interface InjectedGraphQLProps<T> {
data?: T;
loading?: boolean;
}
export interface FixedComponentClass<P> extends ComponentClass<P> {
new (props?: P, context?: any): React.Component<P, any>;
}
export type ComponentClass<P> = React.ComponentClass<P>;
export type StatelessComponent<P> = React.StatelessComponent<P>;
export interface WrapWithApollo<QueryProps, ComponentProps> {
(
WrappedComponent: (
ComponentClass<ComponentProps & InjectedGraphQLProps<QueryProps>> |
StatelessComponent<ComponentProps & InjectedGraphQLProps<QueryProps>> | any
)
): (FixedComponentClass<ComponentProps>);
}
export default function graphql<QueryProps, ComponentProps>(/* args */) {
const wrapWithApolloComponent: WrapWithApollo<QueryProps, ComponentProps> = WrappedComponent => {
/* body */
}
} and this works with: export interface ITest1Props {
x: boolean;
}
export interface ITest1QueryProps {
a: string;
b: number;
}
export type IProps = ITest1Props & InjectedGraphQLProps<ITest1QueryProps>;
export class Test1 extends Component<IProps, {}> {
componentWillReceiveProps(props) {
}
render (): JSX.Element { return <div>{this.props.data.a}</div>; }
}
export const Test1Out = graphql<ITest1QueryProps, ITest1Props>(null!)(Test1);
class Test1Wrapper extends Component<{}, {}> {
componentWillReceiveProps(props) {
}
render (): JSX.Element {
return <Test1Out x={true} />;
}
}
@graphql<ITest1QueryProps, ITest1Props>(null!)
export class Test2 extends React.Component<IProps, {}> {
render (): JSX.Element {
return <div>{ this.props.data.a }</div>;
}
}
class Test2Wrapper extends Component<{}, {}> {
render (): JSX.Element {
return <Test2 x={false} />;
}
}
const Test3: (props: ITest1Props) => JSX.Element = (props: ITest1Props) => <div />;
const Test3Out = graphql<ITest1QueryProps, ITest1Props>(null!)(Test3);
class Test3Wrapper extends Component<{}, {}> {
render (): JSX.Element {
return <Test3Out x={false} />;
}
} but it fails with: @graphql<any, any>(null!)
class TestFail extends React.Component<any, any> {
componentWillReceiveProps(props) {
}
render() {
return null;
}
} because
i'm sure something like https://github.com/DefinitelyTyped/DefinitelyTyped/blob/types-2.0/react-redux/index.d.ts#L26 is needed for the decorator, but that breaks it for the class/stateless component 😞 i'll keep looking, but any help would be appreciated |
actually can just take the thing from react-redux and make the props from react-apollo optional and able to be generated with the InjectGraphQLProps interface |
Steps to Reproduce
Describe how to reproduce this issue.
component1.tsx
:component2.tsx
:Buggy Behavior
The above will compile, because
react-apollo
has typings:Expected Behavior
This shouldn't compile, because prop
bar
is missing andfoo
is of the wrong type.I'm thinking that the
graphql
HOC can take generics like:(did this pretty quickly, probably not 100% accurate, see react-redux typings)
Version
Notes
I searched the issues and didn't see anything about this.
I'd be willing to make a PR if such a thing would be acceptable
The text was updated successfully, but these errors were encountered: