defer()不再允许可观察的返回类型

时间:2018-10-20 03:00:58

标签: rxjs ngrx-effects

今天我从6号角升级到7号角

与此同时,我不得不将rxjs从6.1.0升级到6.3.3,并将打字稿从2.7.2升级到3.1.1

现在,此ngrx效果方法抛出了打字错误:

  @Effect()
  init$ = defer(() => {
    const userData = localStorage.getItem('user');
    return (userData)
      ? of(new Login(JSON.parse(userData)))
      : of(new Logout());
  });
  

'()=>类型的参数可观察|可观察的不是   可分配给类型'()=> void |的参数可订阅|   可订阅|承诺| InteropObservable”。

似乎我不再可以使用defer来分派这样的操作,因此我不确定如何编写前进的初始化效果。

我只需要等待存储初始化,因此在这种方法中,我将执行推迟到效果订阅动作流为止。

有人知道我该如何解决吗?

更新:

我还找到了一个利用ROOT_EFFECTS_INIT的{​​{3}}示例,但是由于我位于功能模块中,因此该方法不起作用(Stackblitz

import { ROOT_EFFECTS_INIT } from '@ngrx/effects';

@Effect()
  init$ = this.actions$
    .ofType(ROOT_EFFECTS_INIT)
    .pipe(
      map(() => {
        const userData = localStorage.getItem('user');
        return (userData)
          ? of(new Login(JSON.parse(userData)))
          : of(new Logout())
      })
    );

1 个答案:

答案 0 :(得分:8)

这是TypeScript的限制。您可以通过在箭头函数中显式指定返回类型来解决此问题:

@Effect()
init$ = defer((): Observable<Action> => { // HERE
  const userData = localStorage.getItem('user');
  return (userData)
    ? of(new Login(JSON.parse(userData)))
    : of(new Logout());
});

或者,更具体地说:

@Effect()
init$ = defer((): Observable<Login | Logout> => { // HERE
  const userData = localStorage.getItem('user');
  return (userData)
    ? of(new Login(JSON.parse(userData)))
    : of(new Logout());
});

问题在于,如果没有显式的返回类型,则将箭头函数的返回类型推断为:

Observable<Login> | Observable<Logout>

而不是:

Observable<Login | Logout>

有趣的是,尽管确实是TypeScript的局限性,this RxJS PR可以解决问题,并且可以推断出正确的类型。