reactjs - React + Redux-Observable + Typescript - 编译,参数不可分配错误
问题描述
我正在使用 React 和 Redux-Observable 创建一个应用程序。我是新手,我正在尝试创建一个史诗来执行用户登录。
我的史诗如下:
export const loginUserEpic = (action$: ActionsObservable<Action>) =>
action$.pipe(
ofType<LoginAction>(LoginActionTypes.LOGIN_ACTION),
switchMap((action: LoginAction) =>
ajax({
url,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: { email: action.payload.username, password: action.payload.password },
}).pipe(
map((response: AjaxResponse) => loginSuccess(response.response.token)),
catchError((error: Error) => of(loginFailed(error))),
),
),
);
问题是我在这一行收到一个 Typescript 错误:ofType<LoginAction>(LoginActionTypes.LOGIN_ACTION)
这样说:
Argument of type '(source: Observable<LoginAction>) => Observable<LoginAction>' is not assignable to parameter of type 'OperatorFunction<Action<any>, LoginAction>'.
Types of parameters 'source' and 'source' are incompatible.
Type 'Observable<Action<any>>' is not assignable to type 'Observable<LoginAction>'.
Type 'Action<any>' is not assignable to type 'LoginAction'.
Property 'payload' is missing in type 'Action<any>'.
我的行动在这里:
export enum LoginActionTypes {
LOGIN_ACTION = 'login',
LOGIN_SUCCESS_ACTION = 'login-sucesss',
LOGIN_FAILED_ACTION = 'login-failed',
}
export interface LoginAction extends Action {
type: LoginActionTypes.LOGIN_ACTION;
payload: {
username: string;
password: string;
};
}
export function login(username: string, password: string): LoginAction {
return {
type: LoginActionTypes.LOGIN_ACTION,
payload: { username, password },
};
}
export interface LoginSuccessAction extends Action {
type: LoginActionTypes.LOGIN_SUCCESS_ACTION;
payload: {
loginToken: string;
};
}
export function loginSuccess(loginToken: string): LoginSuccessAction {
return {
type: LoginActionTypes.LOGIN_SUCCESS_ACTION,
payload: { loginToken },
};
}
export interface LoginFailedAction extends Action {
type: LoginActionTypes.LOGIN_FAILED_ACTION;
payload: {
error: Error;
};
}
export function loginFailed(error: Error): LoginFailedAction {
return {
type: LoginActionTypes.LOGIN_FAILED_ACTION,
payload: { error },
};
}
export type LoginActions = LoginAction | LoginSuccessAction | LoginFailedAction;
如何在不使用any
Epic 上的类型的情况下解决此问题?
解决方案
提供的ofType
运算符redux-observable
并不是区分联合类型的最佳方法。一个更好的方法是isOfType
使用typesafe-actions
.
import { filter } from 'rxjs/operators';
import { isOfType } from 'typesafe-actions';
首先,让我们告诉 TypeScript 您的应用程序中可能使用的操作。您的操作流不应定义为ActionsObservable<Action>
,而应定义为您的操作流:ActionsObservable<LoginActions>
。
export const loginUserEpic = (action$: ActionsObservable<LoginActions>) =>
现在我们可以将isOfType
谓词与filter
运算符一起使用。替换这个:
ofType<LoginAction>(LoginActionTypes.LOGIN_ACTION)
有了这个:
filter(isOfType(LoginActionTypes.LOGIN_ACTION))
沿流传递的动作将被正确识别为LoginAction
.
推荐阅读
- laravel - 我可以有条件地在我的页面上渲染 Livewire 组件吗(就像在 Vue 中一样)?
- search - 如果在网上商店中设置为私有,我可以找到我的 google chrome 扩展程序吗?
- html - 我无法让我的导航占用我的 flexbox。导航只占用了它所在框的一小部分
- sql - DB2 Toad SQL - 使用 Max 命令按某些列分组
- json - 如何将特殊格式的数据导入 Elasticsearch?
- regex - 如何使用 realline() 使用正则表达式在文件中查找匹配项并将它们打印到控制台
- reactjs - REact js noob here,如何在循环遍历带有键的数组时更改状态对象值
- ios - Swift 如何从实时网站中抓取前 500 或 1000 个顶级网站?
- amazon-web-services - 预配置 EC2 上的 AWS 系统设计
- laravel - 如何在 Laravel 中使用一个用户模型创建单独的登录视图和重定向