繁体   English   中英

如何正确输入 fp-ts ObservableEither#fold?

[英]How to properly type fp-ts ObservableEither#fold?

我正在尝试使用 fp-ts 和 redux-observable 来构建一些处理一些 api 请求的史诗。 我遇到了fp-ts-rxjs/ObservableEither#fold的问题,如果我不将我的操作转换为AnyAction类型,我会收到一个类型错误,指出这两种类型应该是相同的。

Type 'Observable<{ payload: { user: User<Attributes>; }; type: string; }>' is not assignable to type 'Observable<{ payload: { error: Error | null; }; type: string; }>'.
  Type '{ payload: { user: User<Attributes>; }; type: string; }' is not assignable to type '{ payload: { error: Error | null; }; type: string; }'.
    Types of property 'payload' are incompatible.
      Property 'error' is missing in type '{ user: User<Attributes>; }' but required in type '{ error: Error | null; }'

我也尝试过使用fp-ts-rxjs/ObservableEither#bimap因为它期望返回两种不同的类型。 但是,这会导致运行时错误,指出操作不能具有未定义的类型。 我也不确定那里到底发生了什么。

LoginSlice.ts

const loginSlice = createSlice({
  name: 'login',
  initialState,
  reducers: {
    loginSuccess (state, action: PayloadAction<{ user: User }>) {
      state.loggedIn = true;
    },

    loginReset (state) {
      state.error = null;
    },

    loginFail (state, action: PayloadAction<{ error: Error | null } >) {
      state.error = action.payload.error;
    }
  }
});

LoginService.ts

const loginService = (credentials: LoginInfo): OE.ObservableEither<Error, User> => {
  const { username, password } = credentials;

  return OE.fromTaskEither(
    TE.tryCatch(
      async () => await User.logIn(username, password),
      error => error as Error
    )
  );
};

LoginEpics.ts

export const loginEpic: Epic = (action$: ActionsObservable<AnyAction>) => action$.pipe(
  filter(login.match),
  mergeMap((action) =>
    loginService(action.payload.credentials).pipe(
      fold(
        (error) => of(loginFail({ error }) as AnyAction),
        (user) => of(loginSuccess({ user }) as AnyAction)
      )
    )
  )
);

有没有办法避免将动作转换为AnyAction 任何见解将不胜感激。

我不熟悉fp-ts-rxjs/ObservableEither ,但是如果它们的fold function 的定义与常规fp-ts折叠函数的定义方式类似,我认为您的问题可以通过指定一个或两个的确切返回类型来解决您传递给fold的匿名函数。

当没有指定返回类型时,TypeScript 试图从第一个 function 推断返回类型并且不够聪明,没有意识到因为两个匿名函数返回不同的类型,折叠结果应该是两个返回类型的联合。

假设您有LoginFailureLoginSuccess操作类型,没有AnyAction的折叠看起来像:

fold(
  (error): LoginFailure | LoginSuccess => of(loginFail({ error })),
  (user): LoginFailure | LoginSuccess => of(loginSuccess({ user }))
)

这里我们指定返回类型应该是可能返回的操作的联合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM