Skip to content

Commit

Permalink
[react-router] Fix #38271 (withRouter fails with ComponentType st…
Browse files Browse the repository at this point in the history
…arting in 3.6.2) (#38326)

* Make withRouter compatible with ComponentType

Fixes #38271.

* Add new baselines

Co-authored-by: Oliver Joseph Ash <oliverjash@gmail.com>
  • Loading branch information
2 people authored and orta committed Sep 17, 2019
1 parent de340a4 commit 37d97cd
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
10 changes: 7 additions & 3 deletions types/react-router/index.d.ts
Expand Up @@ -143,8 +143,12 @@ export interface WithRouterStatics<C extends React.ComponentType<any>> {
// they are decorating. Due to this, if you are using @withRouter decorator in your code,
// you will see a bunch of errors from TypeScript. The current workaround is to use withRouter() as a function call
// on a separate line instead of as a decorator.
export function withRouter<P extends RouteComponentProps<any>, C extends React.ComponentType<P>>(
component: C & React.ComponentType<P>,
): React.ComponentClass<Omit<P, keyof RouteComponentProps<any>> & WithRouterProps<C>> & WithRouterStatics<C>;
export function withRouter<C extends React.ComponentType<RouteComponentProps>>(

This comment has been minimized.

Copy link
@tenshouuu

tenshouuu Sep 18, 2019

Pease, add any or mixable type instead RouteComponentProps --> type RouteComponentProps & any. My custom props typing doesnt work with withRouter. Fix it please!!!

test it:

type Props = RouteComponentProps & MyProps;
const MyComponent: FunctionComponent<Props> = () => ....;
export default withRouter(MyComponent);
component: C,
): React.ComponentClass<
Omit<React.ComponentProps<C>, keyof RouteComponentProps> & WithRouterProps<C>,
never
> &
WithRouterStatics<C>;

export const __RouterContext: React.Context<RouteComponentProps>;
8 changes: 8 additions & 0 deletions types/react-router/test/WithRouter.tsx
Expand Up @@ -9,13 +9,21 @@ const ComponentFunction = (props: TOwnProps) => (
<h2>Welcome {props.username}</h2>
);

const FunctionComponent: React.FunctionComponent<TOwnProps> = props => (
<h2>Welcome {props.username}</h2>
);

declare const Component: React.ComponentType<TOwnProps>;

class ComponentClass extends React.Component<TOwnProps> {
render() {
return <h2>Welcome {this.props.username}</h2>;
}
}

const WithRouterComponentFunction = withRouter(ComponentFunction);
const WithRouterFunctionComponent = withRouter(FunctionComponent);
const WithRouterComponent = withRouter(Component);
const WithRouterComponentClass = withRouter(ComponentClass);
WithRouterComponentClass.WrappedComponent; // $ExpectType typeof ComponentClass

Expand Down

1 comment on commit 37d97cd

@santaclauze
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@orta , @karol-majewski , @OliverJAsh , Hey sorry for posting here, i am not sure if this is the best place to do so either but I cannot find an anwer to my issue.

I was using withRouter and typed it this way:

interface IProps extends RouteComponentProps<{}> {
  onSubmit: (password: string, firstName: string, lastName: string) => void;
}

const SetPasswordForm = (props: IProps) => {
   ...
}

export default withRouter(SetPasswordForm);

This was working until this commit. Error is:

Argument of type '(props: IProps) => Element' is not assignable to parameter of type 'ComponentType<RouteComponentProps<{}, StaticContext, any>>'.
  Type '(props: IProps) => Element' is not assignable to type 'FunctionComponent<RouteComponentProps<{}, StaticContext, any>>'.
    Types of parameters 'props' and 'props' are incompatible.
      Property 'onSubmit' is missing in type 'RouteComponentProps<{}, StaticContext, any> & { children?: ReactNode; }' but required in type 'IProps'.  TS2345

    93 | };
    94 | 
  > 95 | export default withRouter(SetPasswordForm);

I'm not a typescript ninja yet, and my research have led me nowhere. Is there something that I am doing wrong?

Please sign in to comment.