【问题标题】:How to automatically generate typescript interfaces for redux connected components如何为 redux 连接的组件自动生成 typescript 接口
【发布时间】:2020-01-30 16:46:12
【问题描述】:

有没有办法使用mapStateToPropsmapDispatchToProps的类型自动扩展连接组件的接口?例如以下代码:

interface ComponentProps {
  state?: State;
  action?: (id: string) => void;
}

const mapStateToProps = (state: any) => ({
  state: state,
});

const mapDispatchToProps = (dispatch: any) => ({
  action: (id: string) => dispatch(Action),
});

const Component = (props: ComponentProps) => <div>...</div>;

export const ConnectedComponent = connect(
  mapStateToProps,
  mapDispatchToProps,
)(Component);

要求我将stateaction 作为可选道具添加到我的ComponentProps 以便在我的组件中使用它们,因为道具将由connect HOC 分配。

当使用 materialUI 及其withStyles HOC 之类的东西时,我们可以使用WithStyles&lt;typeof styles&gt; 自动将classes 属性(确切的键取决于styles)添加到我们的界面中,例如

ComponentProps extends WithStyles<typeof styles> {
  actualProps: any;
}

const ConnectedComponent = withStyles(styles)(Component);

是否可以为connect 做同样的事情?

【问题讨论】:

    标签: javascript reactjs typescript redux redux-thunk


    【解决方案1】:

    这是在react-redux-typescript-guide 中的操作方式:

    import Types from 'MyTypes';
    import { bindActionCreators, Dispatch } from 'redux';
    import { connect } from 'react-redux';
    import * as React from 'react';
    
    import { countersActions } from '../features/counters';
    
    // Thunk Action
    const incrementWithDelay = () => async (dispatch: Dispatch): Promise<void> => {
      setTimeout(() => dispatch(countersActions.increment()), 1000);
    };
    
    const mapStateToProps = (state: Types.RootState) => ({
      count: state.counters.reduxCounter,
    });
    
    const mapDispatchToProps = (dispatch: Dispatch<Types.RootAction>) =>
      bindActionCreators(
        {
          onIncrement: incrementWithDelay,
        },
        dispatch
      );
    
    type Props = ReturnType<typeof mapStateToProps> &
      ReturnType<typeof mapDispatchToProps> & {
        label: string;
      };
    
    export const FCCounter: React.FC<Props> = props => {
      const { label, count, onIncrement } = props;
    
      const handleIncrement = () => {
        // Thunk action is correctly typed as promise
        onIncrement().then(() => {
          // ...
        });
      };
    
      return (
        <div>
          <span>
            {label}: {count}
          </span>
          <button type="button" onClick={handleIncrement}>
            {`Increment`}
          </button>
        </div>
      );
    };
    
    export const FCCounterConnectedBindActionCreators = connect(
      mapStateToProps,
      mapDispatchToProps
    )(FCCounter);
    

    你应该使用ReturnType助手:

    type Props = ReturnType<typeof mapStateToProps> & ReturnType<typeof mapDispatchToProps> {
      label: string;
    };
    

    【讨论】:

      猜你喜欢
      • 2019-01-09
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      • 2011-07-03
      • 2017-04-04
      相关资源
      最近更新 更多