关于javascript:如何为Redux连接的组件自动生成Typescript接口

How to automatically generate typescript interfaces for redux connected components

是否可以使用mapStateToPropsmapDispatchToProps类型自动扩展连接组件的接口?例如,以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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) => ...;

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

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

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

1
2
3
4
5
ComponentProps extends WithStyles<typeof styles> {
  actualProps: any;
}

const ConnectedComponent = withStyles(styles)(Component);

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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 (
   
      <span>
        {label}: {count}
      </span>
      <button type="button" onClick={handleIncrement}>
        {`Increment`}
      </button>
   
  );
};

export const FCCounterConnectedBindActionCreators = connect(
  mapStateToProps,
  mapDispatchToProps
)(FCCounter);

您应该使用ReturnType助手:

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