如何在打字稿中为 react thunk 声明类型并重用组件依赖?

How to declare a type for react thunk in typescript and reuse for component dependency?

更新于 2020-06-27 0950am !

这是我的示例代码笔:

actions.tsx:

import { RootState } from "../../index";
import { Action } from "redux";
import { ThunkAction } from "redux-thunk";
import { actionTypes as at } from "./actionTypes";

type shapePayload = {
  message: string;
};

const acExample = (
  payload: shapePayload
): ThunkAction<void, RootState, unknown, Action<string>> => dispatch => {
  const { message } = payload;
  return dispatch({
    type: at.AC_TYPE_EXAMPLE,
    payload: {
      message,
      somethingelse: true
    }
  });
};

export type shapeExample = ReturnType<typeof acExample>;

export { acExample };

Component.tsx

import React, { FC } from "react";
import { connect } from "react-redux";
import { shapeExample, acExample } from "../store/examples/actions";

type shape = {
  acExample: shapeExample;
};
const ExampleActionCreator: FC<shape> = ({ acExample }) => (
  <button
    onClick={() => {
      acExample({ message: "cheese" });
    }}
  >
    trigger store update
  </button>
);

export default connect(
  () => ({}),
  {
    acExample
  }
)(ExampleActionCreator);

当你转到组件 - codesandbox.io/s/exampleactioncreator-rh0sm?file=/src/….

悬停文本 - acExample,

expected 3 arguments but got one

...并悬停文本 - Example Action Creator - 查看打字稿错误
Error TypeScript Argument of type 'FC' is not assignable to parameter of type 'ComponentType<Matching<{ acExample: (payload: shapePayload) => void; }, shape>>'. Type 'FunctionComponent' is not assignable to type 'FunctionComponent<Matching<{ acExample: (payload: shapePayload) => void; }, shape>>'. Types of property 'propTypes' are incompatible. Type 'WeakValidationMap | undefined' is not assignable to type 'WeakValidationMap<Matching<{ acExample: (payload: shapePayload) => void; }, shape>> | undefined'. Type 'WeakValidationMap' is not assignable to type 'WeakValidationMap<Matching<{ acExample: (payload: shapePayload) => void; }, shape>>'. Types of property 'acExample' are incompatible. Type 'Validator<ThunkAction<void, any, unknown, Action>> | undefined' is not assignable to type 'Validator<(payload: shapePayload) => void> | undefined'. Type 'Validator<ThunkAction<void, any, unknown, Action>>' is not assignable to type 'Validator<(payload: shapePayload) => void>'. Type 'ThunkAction<void, any, unknown, Action>' is not assignable to type '(payload: shapePayload) => void'.

谢谢

好的,经过大量在线搜索后 - 我找到了解决问题的方法。看来我必须声明 use - bindActionCreators 以便我可以传入类型。如下:

action.ts

import {RootState} from 'src/index';
import { Action } from 'redux'
import { ThunkAction } from 'redux-thunk';
import { actionTypes as at } from './actionTypes';

export type shapeExample = (
  payload: {
    message: string
  }
) => ThunkAction<void, RootState, undefined, Action>;

const acExample:shapeExample = payload => dispatch => {
  const {message} = payload;
  dispatch({
    type: at.AC_TYPE_EXAMPLE,
    payload: {
      message,
      somethingelse: true
    }
  });
}

export {
  acExample
};

Component.tsx

import React, {FC} from 'react';
import {bindActionCreators, Action} from 'redux';
import {ThunkDispatch} from 'redux-thunk';
import { connect} from 'react-redux';
import {shapeExample, acExample} from 'src/store/examples/actions';
import {RootState} from 'src/index';

type shape = {
  acExample: shapeExample
};

const myComponent:FC<shape> = ({acExample}) => (
  <button onClick={() => {
    acExample({message: 'cheese'});
  }} >
    trigger store update
  </button>
);

const mapDispatchToProps = (dispatch: ThunkDispatch<RootState, undefined, Action>) =>
  bindActionCreators(
    {acExample},
    dispatch
  );

export default connect(
  null,
  mapDispatchToProps
)(myComponent);