如何使用withRouter,connect,React.Component和自定义属性来输入TypeScript?

chm*_*lot 11 typescript reactjs react-router react-redux typescript2.0

我有一个阵营Component使用connect,withRouter并接收自定义属性.我试图将其转换为TypeScript,我想知道我是否正确地这样做.至少,我现在没有错误.

这是显示概念的代码:

import * as React from 'react'
import { connect } from 'react-redux';
import { withRouter, RouteComponentProps } from 'react-router';

import { 
  fetchTestLists,
  newTestList,
  displayTestList,
} from '../../../actions/index';

interface StateProps {
  testList: any;    // todo: use the type of state.myList to have validation on it
}

interface DispatchProps {
  fetchTestLists: () => void;
  newTestList: () => void;
  displayTestList: (any) => void;   // todo: replace any with the actual type
}

interface Props {      // custom properties passed to component
  className: string;
}

type PropsType = StateProps & DispatchProps & Props;


class MyTest extends React.Component<PropsType & RouteComponentProps<{}>, {}> {
  constructor(props) {
    super(props);
    this.handleCellClick = this.handleCellClick.bind(this);
    this.newTestList = this.newTestList.bind(this);
  }

  componentDidMount() {
    this.props.fetchTestLists();
  }

  handleCellClick(row, column, event) {
    this.props.displayTestList(row);
  }

  newTestList(e) {
    this.props.newTestList()
  }

  render() {
    return (
      <div className={this.props.className}>
      </div>
    );
  }
}

const mapStateToProps = (state): StateProps => ({
  testList: state.myList,   // todo: define a type for the root state to have validation here
});

const dispatchToProps = {
  fetchTestLists,
  newTestList,
  displayTestList,
};

export default withRouter<Props & RouteComponentProps<{}>>(connect<StateProps, DispatchProps>(
  mapStateToProps,
  dispatchToProps,
)(MyTest) as any);
Run Code Online (Sandbox Code Playgroud)

该组件使用如下: <MyTest className={"active"} />

我必须做很多实验才能使这个工作.例如:

1)当我省略withRouter的类型时: export default withRouter(connect... 我得到TS2339: Property 'className' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<Pick<RouteComponentProps<any>, never>, C...'. 这已经在某种程度上被建议:在TypeScript中反应路由器 - 路由器和自己的道具,虽然我不了解这个概念.

2)如果你想知道最后一行as any,这与https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18999有关,我收到此错误没有它:

 TS2345: Argument of type 'ComponentClass<Pick<any, never>> & { WrappedComponent: ComponentType<any>; }' is not assignable to parameter of type 'ComponentType<Props & RouteComponentProps<{}>>'.
 Type 'ComponentClass<Pick<any, never>> & { WrappedComponent: ComponentType<any>; }' is not assignable to type 'StatelessComponent<Props & RouteComponentProps<{}>>'.
 Type 'ComponentClass<Pick<any, never>> & { WrappedComponent: ComponentType<any>; }' provides no match for the signature '(props: Props & RouteComponentProps<{}> & { children?: ReactNode; }, context?: any): ReactElement<any> | null'.
Run Code Online (Sandbox Code Playgroud)

那么这是正确的方法吗?你在哪里看到问题?我基本上使用所有最新版本,这是我的package.json的一个片段:

"react": "^16.2.0",
"redux": "^3.7.2",
"react-dom": "^16.2.0",
"react-redux": "^5.0.6",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-router-redux": "^4.0.8",
...
"typescript": "^2.7.2",
"@types/react-redux": "^5.0.15",
"@types/react-router": "^4.0.22",
"@types/react-router-dom": "^4.2.4",
"@types/react": "^16.0.38",
"@types/react-dom": "^16.0.4",
Run Code Online (Sandbox Code Playgroud)

Kac*_*992 7

我如何在我们的项目中做到这一点(这是最简单的方法,您可以在使用它时获得智能感知):

import * as React from 'react'
import { connect } from 'react-redux';
import { withRouter, RouteComponentProps } from 'react-router';

import { 
  fetchTestLists,
  newTestList,
  displayTestList,
} from '../../../actions/index';

interface StateProps {
  testList: any;    // todo: use the type of state.myList to have validation on it
}

interface DispatchProps {
  fetchTestLists: () => void;
  newTestList: () => void;
  displayTestList: (any) => void;   // todo: replace any with the actual type
}

interface Props extends RouteComponentProps {      // custom properties passed to component
  className: string;
}

type PropsType = StateProps & DispatchProps & Props;


class MyTest extends React.Component<PropsType> {
  constructor(props) {
    super(props);
    this.handleCellClick = this.handleCellClick.bind(this);
    this.newTestList = this.newTestList.bind(this);
  }

  componentDidMount() {
    this.props.fetchTestLists();
  }

  handleCellClick(row, column, event) {
    this.props.displayTestList(row);
  }

  newTestList(e) {
    this.props.newTestList()
  }

  render() {
    return (
      <div className={this.props.className}>
      </div>
    );
  }
}

const mapStateToProps = (state, ownProps: Props): StateProps => ({
  testList: state.myList,   // todo: define a type for the root state to have validation here
});

const dispatchToProps: DispatchProps = {
  fetchTestLists,
  newTestList,
  displayTestList,
};

export default withRouter(connect(
  mapStateToProps,
  dispatchToProps,
)(MyTest));
Run Code Online (Sandbox Code Playgroud)

此外,如果这是您经常输入的内容,我建议您编写一个自定义代码段(如果您使用的是 VS Code 之类的东西,这很容易)。


小智 -6

我通过强制安装 @types/react-redux 包解决了这个问题。我刚刚从 4.4.5 更新到 5.0.15。

运行一个新的npm install --save @types/react-redux@5.0.15.