这里是typescript + redux生态系统的新手。
在TypeScript中使用redux-actions、redux-thunk和redux-promise中间件时,如何正确地将类型信息封装到异步操作中?
以下是身份验证的示例:
/* actions */
const login = createAction(LOGIN, authService.login);
/* authService */
async function login(payload: LoginPayload): Promise<LoginResponse> {
// ... authenticate here.
}由于我使用的是redux-promise-中间件,因此会自动分派LOGIN_PENDING、LOGIN_FULFILLED/LOGIN_REJECTED操作。我如何为这些类型创建类型,以便reducer可以确定它正在处理的是什么操作对象?
因为redux-actions遵循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还为此提供了Action和BaseAction类型。
发布于 2017-10-18 19:14:29
要做到这一点,“正常”的方法是指定所有“操作接口”和一个向下延伸到reducer的联合类型。然后打开类型。但从示例代码看,不清楚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
}
}您可能可以使用一些泛型以更智能的方式创建此联合,但这是手动方法。
发布于 2019-12-20 23:00:41
我建议使用createAsyncAction而不是createAction。这样,您就可以按如下方式定义类型:
/* actions */
const login = createAsyncAction<
typeof LOGIN,
LoginResponse, // no need to wrap in Promise<>
null, // this is optional Meta,
[LoginPayload] // action creator arguments wrapped in array
>(LOGIN, authService.login);但我恐怕不知道什么时候login是个垃圾:
/* actions */
const loginAction = createAsyncAction(LOGIN, authService.login)
const loginActionCreator = (data: LoginPayload) => async(dispatch: Dispatch) => {
await dispatch(loginAction(data));
}
// ERROR: () => void is not assignable to () => (dispatch) => void (pseudo code)https://stackoverflow.com/questions/46806840
复制相似问题