React Router-ошибки Typescript на withRouter после обновления версии

Я просто попытался обновить приложение React до

react-router-4.0.19 до 4.0.20

реагировать-16.0.30 до 16.0.34

typescript-версия " 2.7.0-инсайдеры.20180108"

в моем приложении, где бы я ни использовал "withRouter", теперь я получаю загадочные ошибки Typescript. Я даже заменил все реквизиты интерфейса на "любой", чтобы попытаться заставить его работать.

import * as React from 'react';
import { Switch, Route, withRouter} from 'react-router-dom';
import { Login } from './Login';
import { connect } from 'react-redux';
import { RootAction, RootState } from './_redux';

class MainForm extends React.Component<any> {

  constructor(props: any) {
    super(props);
  }

  render() {

    return (
      <Switch>
        <Route exact={true} path="/" component={Login}/>
        <Route  path="/accounts" component={AccountsView}/>
      </Switch> 
    );
  }
}

const mapStateToProps = (state: RootState) => ({
  state
});

export const Main = withRouter(connect(mapStateToProps)(MainForm);

ошибка TS2345: аргумент типа ' ComponentClass> & { WrappedComponent: ComponentType;} ' не присваивается параметр типа 'ComponentType>'. Тип 'ComponentClass> & { WrappedComponent: ComponentType;} ' не присваивается типу 'StatelessComponent>'. Тип 'ComponentClass> & { WrappedComponent: ComponentType;}' не соответствует сигнатуре '(реквизит: RouteComponentProps & { дети?: ReactNode;}, контекст?: любой): ReactElement / null'.

Если я преобразую последнюю строку на эту :

export const Main = connect(mapStateToProps)(MainForm);

Я не сделать ошибки. серьезно расстроен здесь. Спасибо

редактировать поменял на

export const Main = connect(mapStateToProps)(withRouter(MainForm));

как предложил Майянк Шукла. но теперь получите ошибку:

ошибка TS2345: аргумент типа 'ComponentClass>' является не присваивается параметру типа ' ComponentType'. Тип ComponentClass> - это не присваивается типу ' StatelessComponent'. Тип 'ComponentClass>' не соответствует сигнатуре '(props: { state: RootState;} & DispatchProp & { дети?: ReactNode;}, контекст?: any): ReactElement / null'.

3 ответов


Я только что обновился до TypeScript 2.6 и получил ту же проблему.

мне удалось решить его с помощью RouteComponentProps.

для URL http://localhost:8080/your-component/abc и по маршруту

<Route component={YourComponent} path="/your-component/:param1?" />

компонент должен выглядеть так:

import * as React from 'react'
import { withRouter } from 'react-router-dom';
import {RouteComponentProps} from "react-router";

// Type whatever you expect in 'this.props.match.params.*'
type PathParamsType = {
    param1: string,
}

// Your component own properties
type PropsType = RouteComponentProps<PathParamsType> & {
    someString: string,
}

class YourComponent extends React.Component<PropsType> {
    render() {

        console.log(this.props); // Prints all props including routing-related
        console.log(this.props.match.params.param1); // Prints 'abc'
        console.log(typeof this.props.match.params.param1 === 'string'); // prints 'true'

        return <div>...</div>;
    }
}

export default withRouter(YourComponent);

другое решение, используя декораторы

import { withRouter, RouteComponentProps } from "react-router";

// inform we match url /:id
interface IMatchParams {
    id: string;
}

// Note we use Partial<RouteComponentProps> to make all RouteComponentProps as optional for high order component
interface IComponentProps extends Partial<RouteComponentProps<IMatchParams>> {
    myPersonalProp: string;
}

@withRouter
export default class MyClass extends React.Component<IComponentProps>{

    public componentDidMount(){
        console.log(this.props.match.params.id);
    }
}

вот как я обычно структурирую мои типизированные компоненты React:

// These props are provided when creating the component
interface OwnProps {
    // ...
}

// These props are provided via connecting the component to the store
interface StateProps {
    // ...
}

// These props are provided by the router
interface PathProps {
    // ...
}

class Component extends React.Component<OwnProps & StateProps & RouteComponentProps<PathProps>> {
    // ...
}

const mapStateToProps = (state: State, props: OwnProps): StateProps => ({
    // ...
});

export default withRouter(
    connect(mapStateToProps)(Component)
);