如何在打字稿中为 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);
更新于 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
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);