Typescript 财产';然后';通过bindActionCreators绑定的函数上不存在
我已经按照官方的Redux指南创建了thunk动作创建者,这样我就可以在react组件中使用绑定动作。但是,我的组件无法识别函数返回的承诺,因此我不能使用Typescript 财产';然后';通过bindActionCreators绑定的函数上不存在,typescript,redux,react-redux,Typescript,Redux,React Redux,我已经按照官方的Redux指南创建了thunk动作创建者,这样我就可以在react组件中使用绑定动作。但是,我的组件无法识别函数返回的承诺,因此我不能使用then,这也意味着我无权访问函数的返回值 以下是我的action creator代码示例: // Temp State for now, not important type IAppState = any; // Just a sample response object interface ISampleThunkResponse {
then
,这也意味着我无权访问函数的返回值
以下是我的action creator代码示例:
// Temp State for now, not important
type IAppState = any;
// Just a sample response object
interface ISampleThunkResponse {
text: string;
active: boolean;
}
// Thunk action
export function sampleThunk(
text: string
): ThunkAction<Promise<ISampleThunkResponse>, IAppState, null, Action<string>> {
return async (dispatch, getState): Promise<ISampleThunkResponse> => {
const apiResponse = await Promise.resolve({ text, active: true });
dispatch({ payload: apiResponse, type: 'SOME_TYPE' });
return apiResponse;
};
}
我希望redux文档中也提供了关键部分,即具有ConnectedProps
类型,以便能够包装连接器
我还将功能性的mapDispatchToProps
转换为对象版本,但就键入而言,这并没有真正改变任何东西
更大的变化是必须将我的connect调用移动到一个变量中,以便使它可用于我的ConnectedProps
的ISampleCompProps
声明sampleThunkConnect
是错误的
thunk action creator+thunk函数的定义方式与传递到组件的绑定道具的类型之间存在差异
最终,this.props.sampleThunkConnect
看起来像(text:string)=>Promise
,因为调度thunk会返回thunk函数返回的结果。但是,您当前使用的是thunk action创建者本身的实际类型,因此导致代码中断
connect
的React-Redux类型有一些奇特的内部类型,可以将thunk“解析为其返回类型。根据和文章中的示例,您可以重用其中一种类型来提取“props fromconnect
”的类型,并让TS自己了解细节
另外,我强烈建议您使用,而不是自己将其作为函数编写。看看您提供的要点,我需要采用的模式几乎是颠倒的。我认为我编写React组件的方式已经过时了。在要点中,他们创建了连接器
,然后用它装饰组件。希望这样做不会对我的代码产生任何影响。我试试看。作为补充说明,您还建议使用对象速记进行mapDispatch,因此在我的代码中这似乎也过时了。我会更新你的评论,做一些重构,然后回来给你一个例子,看看是否一切都好。谢谢好的,我已经重构了我的代码,更新了问题,并在问题解决后关闭了它!谢谢你,马克!嘿,我有一个快速跟进的问题,所以一切正常,除了需要将连接的动作创建者作为道具传递到子组件的情况。因此,我将父组件与3-4个动作创建者连接起来,但其中一个子组件只需要doFetchAppConnected
。我如何在我的子组件道具中键入此内容?我不能简单地做doFetchAppConnected:代码>,因为原始问题。有办法解决这个问题吗?类似于ReturnType
?好吧,我想出来了,下面是你的方法:从'react redux'导入{InferThunkActionCreatorType}代码>导出类型IDoFetchApp=InferThunkActionCreatorType代码>doFetchAppConnected:IDoFetchApp代码>
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { sampleThunk } from './sampleThunk';
import * as React from 'react';
export interface ISampleCompProps {
sampleThunkConnect?: typeof sampleThunk;
}
export function SampleComp(props: ISampleCompProps) {
const {
sampleThunkConnect
} = props;
function handleClick() {
// HERE IS THE ERROR
// Property 'then' does not exist on type 'ThunkAction<Promise<ISampleThunkResponse>, any, null, Action<string>>'.
sampleThunkConnect('SAMPLE TEXT').then(value => console.log(value));
}
return (
<div onClick={handleClick}>Whatever...</div>
);
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
sampleThunkConnect: sampleThunk,
},
dispatch
);
}
export default connect<(
null,
mapDispatchToProps
)(SampleComp);
import { connect } from 'react-redux';
import { sampleThunk } from './sampleThunk';
import * as React from 'react';
import { InferableComponentEnhancerWithProps } from 'react-redux';
// Typing
type ConnectedProps<T> = T extends InferableComponentEnhancerWithProps<infer Props, infer _>
? Props
: never;
type PropsFromRedux = ConnectedProps<typeof connector>;
export interface ISampleCompOwnProps {
uuid: string;
}
type ISampleCompProps = ISampleCompOwnProps & PropsFromRedux;
// Temp State for now, not important
type IAppState = any;
// Redux Connect
const mapDispatchToProps = {
sampleThunkConnect: sampleThunk,
};
const mapStateToProps = (state: IAppState) => ({
someStateKey: state.someStateKey,
});
const connector = connect(
mapStateToProps,
mapDispatchToProps
);
// tslint:disable-next-line function-name
export function SampleComp(props: ISampleCompProps) {
const {
sampleThunkConnect
} = props;
function handleClick() {
// Everything is working now!
sampleThunkConnect('SAMPLE TEXT').then(value => console.log(value));
}
return (
<div onClick={handleClick}>Whatever...</div>
);
}
export default connector(SampleComp);