0

这里是typescript + redux生态系统的新手。在typescript中使用redux-actions,redux-thunk和redux-promise-middleware

在TypeScript中使用redux-actions,redux-thunk和redux-promise-middleware时,如何正确地将类型信息封装为异步操作?

认证的例子:

/* actions */ 
const login = createAction(LOGIN, authService.login); 


/* authService */ 
async function login(payload: LoginPayload): Promise<LoginResponse> { 
// ... authenticate here. 
} 

由于我使用的终极版,承诺中间件,动作LOGIN_PENDINGLOGIN_FULFILLED/LOGIN_REJECTED自动调度。我如何为这些创建类型,使reducer可以找出它正在处理的操作对象?

由于还原操作遵循FSA,因此_FULFILLED应具有action.payload_REJECTED应该有action.error

/* reducer */ 
function loginReducer(state: AppState, action: AuthAction) { 
    switch (action.type) { 
    case LOGIN_FULFILLED: 
     // action.payload should be defined as LoginResponse object here. 
     // action.error shouldnt be present. 
    case LOGIN_REJECTED: 
     // action.error should be defined 
    } 
} 

我怎么会去有关创建AuthAction类型?我猜它应该是每个单独操作类型的联合类型(它们可以是联合类型)。 redux-actions也为此提供ActionBaseAction类型。

回答

0

执行此操作的“常规”方式是将所有“操作接口”和联合类型指定到缩减器。然后打开类型。但是从示例代码,其不清楚AuthAction类型是否是联合类型...

例如,

type T = Object; //Your resolve data type 
interface ILoginAction {type: "LOGIN", payload: {promise: Promise<T> }} 
interface ILoginRejectedAction {type: "LOGIN_REJECTED", error: YourErrorType } 
interface ILoginFulfilledAction {type: "LOGIN_FULFILLED", payload: {data: T }} 

export type LoginActions = ILoginAction | ILoginRejectedAction | ILoginFulfilledAction 

减速机:

import { LoginActions } from "./actions"; //Or where your actions are 
function loginReducer(state: AppState, action: LoginActions) { 
    switch (action.type) { 
    case "LOGIN": 
     // action.payload should be defined as LoginResponse object here. 
     // action.error shouldnt be present. 
    case "LOGIN_REJECTED": 
     // action.error should be defined 
    } 
} 

你或许可以在使用一些仿制药一个更聪明的方式创建这个联盟,但是这是手动方法。

+0

这就是问题所在。什么是'AuthActions',这样每个case块就知道'action'来自哪个接口。为了清晰起见,我编辑了这个问题。 –

+0

然后它的LoginActions联盟键入我上面的答案。 Iv'e通读中间件的.d.ts文件,我可以看到它的任何泛型。所以这意味着你必须像我一样定义它们,并在缩减器中导入union类型。 –