在使用NgRX 8时,我和我的同事在实现效果时经常会遇到奇怪的错误消息。
类型'Observable <未知>'不能分配给类型'Observable <动作> | ((... args:any [])=> Observable
)'
它与类型问题有关。消息如此具体,真是令人讨厌,它标志着完整的效果。这经常出现,而且确实很难解决。
我们想知道是否可以做一些事情来快速发现问题,或者我们是否能够以某种方式破坏消息的信息。
谢谢和欢呼!
答案 0 :(得分:16)
更新-快速版本-注释掉createEffect(() =>
,修复IDE(VSCode)标记的错误,重新添加createEffect(() =>
。
较旧的答案-不需要使用@Effect
,而且不是必需的。
我发现最简单的调试方法是使用@Effect
装饰器以第7版的方式编写,然后使用createEffect
重写。
要调试:
navigateToDashboard$ = createEffect(() =>
this.actions$.pipe(
ofType(teamActions.CREATE_SUPERVISOR_GROUP_SUCCESS),
map((action: teamActions.CreateSupervisorGroupSuccess) => action.payload),
map((team: Team) => team.TeamID),
SwitchMap(id => new routerActions.Go({ path: ['/team', id, 'populate'] }))
)
)
将无用的错误写为(添加装饰器,删除createEffect(() =>
,删除最后的括号),
@Effect()
navigateToDashboard$ = this.actions$.pipe(
ofType(teamActions.CREATE_SUPERVISOR_GROUP_SUCCESS),
map((action: teamActions.CreateSupervisorGroupSuccess) => action.payload),
map((team: Team) => team.TeamID),
SwitchMap(id => new routerActions.Go({ path: ['/team', id, 'populate'] }))
)
现在我们得到了错误
Cannot find name 'SwitchMap'
之后
Type 'Go' is not assignable to type 'ObservableInput<any>'
修复此问题
@Effect()
navigateToDashboard$ = this.actions$.pipe(
ofType(teamActions.CREATE_SUPERVISOR_GROUP_SUCCESS),
map((action: teamActions.CreateSupervisorGroupSuccess) => action.payload),
map((team: Team) => team.TeamID),
switchMap(id => of(new routerActions.Go({ path: ['/team', id, 'populate'] })))
)
现在用NgRx 8项重写。不漂亮,但是可以。
答案 1 :(得分:4)
我遇到了完全相同的问题,在我的情况下,这是因为括号放置错误和导入丢失所致。
这是我调试和解决问题的方法。
将内部管道功能拆分为单个功能。这对我来说是最重要的一步,因为复杂的语法和来自vscode的自动完成括号,有时括号存在于错误的位置,而且不容易找到。这也解决了几乎所有其他问题(缺少导入,错误的返回类型等),因为要调试的代码小得多,而vscode突出显示了子函数中的单个错误。
这是我以前所拥有的
var myString = "John:31,Miranda:28"
var myObj = myString.split(',').reduce(function (obj, part) {
var pieces = part.split(':')
obj[pieces[0]] = pieces[1]
return obj
}, {})
将此更改为以下
performLogin$ = createEffect(() =>
this.actions$.pipe(
ofType(performLogin),
mergeMap(() => this.loginService.performLogin().pipe(
map(() => loginSuccess())
)))
);
我从这种方法中得到的好处还在于,内部管道上的catchError块不会被触发(按照效果示例,它应该可以工作)。因此必须将其包括在外部可管道块中。在此错误被捕获并按预期工作。但仍要弄清楚为什么它不起作用。
总结起来,登录服务会执行以下操作(引发错误或返回Observable为true)
performLogin$ = createEffect(() =>
this.actions$.pipe(
ofType(performLogin),
mergeMap(() => this.performLogin()),
catchError((error ) => { console.log("HELLO"); return EMPTY})
)
);
performLogin() {
return this.loginService.performLogin()
.pipe(map(() => loginSuccess()));
}
希望这会有所帮助。
答案 2 :(得分:4)
在处理此问题并使用ngrx 8官方示例的情况下。
loadMovies$ = createEffect(() => this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
mergeMap(() => this.moviesService.getAll()
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => EMPTY)
))
)
);
便捷的解决方案可以放入“任意”类型。
loadMovies$: any = createEffect((): any => this.actions$.pipe(
ofType('[Movies Page] Load Movies'),
mergeMap(() => this.moviesService.getAll()
.pipe(
map(movies => ({ type: '[Movies API] Movies Loaded Success', payload: movies })),
catchError(() => EMPTY)
))
)
);
别忘了为rxjs运算符导入可观察的东西。
如果要处理动作有效载荷-道具,请定义动作类型。
ofType<MySuperActions>
或
ofType<ReturnType<typeof myAction>>
答案 3 :(得分:0)
请确保您是从这样的操作(强类型).ts文件中调用操作的
effectName$ = createEffect(
() => this.actions$.pipe(
ofType(FeatureActions.actionOne), // this line
map(() => FeatureActions.actionTwo())
)
);
答案 4 :(得分:0)
实际上,您需要将createAction
创建的动作视为函数,然后调用它以返回动作对象。选中此desc。因此,您的of(addCommentFailed)
应该是of(addCommentFailed())
。
答案 5 :(得分:0)
我遇到了这个问题,因为这里缺少导入'of'运算符
// events.effects.ts
...
getEvents$: Observable<Action> = createEffect(
() => this.actions$.pipe(
ofType(EventsActions.getEvents),
switchMap(action =>
this.eventService.getEvents().pipe(
map(events => EventsActions.getEventsSuccess({ events })),
catchError(error => of(EventsActions.getEventsError({ error })))
)
)
)
);
...
我已通过在顶部添加此行代码来修复它
// events.effects.ts
import { Observable, of } from 'rxjs';
...
答案 6 :(得分:0)
我今天遇到了类似的问题(错误消息相同),这是因为TypeScript无法正确推断Array#flatMap
的返回类型。我假设Array#map
,RxJS#map
或任何未明确键入的数组都是相同的。
以下是崩溃的代码:
this.actions$.pipe(
ofType(ActionType),
switchMap((action) => {
return action.cart.flatMap((cartItem: CartItem) => {
if (x) {
return [
ActionCreator1(params1),
ActionCreator2(params2)
];
} else {
return [];
}
}
})
)
所以我得到了相同的错误消息:
类型'Observable <未知>'不可分配给类型'Observable <动作> | ((... args:any [])=> Observable
)'
要修复此问题,我只需要告诉TypeScript我的映射函数返回了Action
数组:
import { Action } from '@ngrx/store';
...
switchMap((action) => {
return action.cart.flatMap((cartItem: CartItem) : Action[] => {
...
此外,使用Action[]
进行输入比使用any
更安全!
答案 7 :(得分:0)
就我而言,我在rxjs运算符之一中使用了lodash运算符。原来,我没有@types/lodash
。 npm i -D @types/lodash
之后,我的问题解决了。
答案 8 :(得分:0)
我为此问题苦了一段时间,直到最后才发现VS代码自动从某个库而不是Observable
导入了rxjs
希望这可以节省不必要的头部撞击。
答案 9 :(得分:0)
我在我的项目中遇到了这个错误并通过添加这个导入来解决它:
import { Observable, of as observableOf, of } from 'rxjs';
答案 10 :(得分:-1)
我也看到了类似的错误。
Type 'Observable<unknown>' is not assignable to type 'Observable<Action> | ((...args: any[]) => Observable<Action>)'
我确定最快可能发生的方法是在|
分隔符之后。
该类型通常为Observable<{something}>
或Observable<{something | another}>
。有一个|
分隔符,第二项不是Observable。这可能是问题所在。
例如,如果可观察对象期望具有Observable<Action>
,但是有一些管道运算符返回Observable<Action>
以外的值。错误消息中的意外类型将附加到预期类型,因为对于“可观察到的”,T在((...args: any[]) => Observable<Action>)
中不存在
我对邮件的解释是
对象的内部类型未知,因为我们不知道期望哪种类型Observable<Action>
= Action
或((...args: any[]) => Observable<Action>)
=未知
如果问题不是立即显而易见的,我只是逐个注释每个管道运算符,然后看看错误是否会解决。如果是这样,那么现在我知道此操作员是问题所在,而不是我专注于操作员并找到问题。
我有兴趣阅读其他用户的回复。这两种方式总是将我指向正确的方向。