piotrwitek / typesafe-actions

Typesafe utilities for "action-creators" in Redux / Flux Architecture
https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox
MIT License
2.41k stars 99 forks source link

Type error when using Epic with AsyncAction #223

Open EmmanueleVilla opened 4 years ago

EmmanueleVilla commented 4 years ago

Description

When intercepting an asyncAction with an epic, I got a compiler error that it's also present on your sample application in the codesandbox

Mandatory info

How to Reproduce

CodeSandbox Link

I do not have a personal codesandbox link, but the exact same error is present in your codesandbox link (https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox) in the file src/feature/todos/epic:

export const loadTodosEpic: Epic<
  RootAction,
  RootAction,
  RootState,
  Services
> = (action$, state$, { api }) =>
  action$.pipe(
    filter(isActionOf(loadTodosAsync.request)),
    switchMap(() =>
      from(api.todos.loadSnapshot()).pipe(
        map(loadTodosAsync.success),
        catchError((message: string) => of(loadTodosAsync.failure(message)))
      )
    )
  );
Il tipo 'Observable<unknown>' non è assegnabile al tipo 'Observable<RouterAction | PayloadAction<"ADD_TODO", Todo> | PayloadAction<"REMOVE_TODO", string> | PayloadMetaAction<"LOAD_TODOS_REQUEST", unknown, unknown> | PayloadAction<"LOAD_TODOS_SUCCESS", Todo[]> | PayloadAction<...> | PayloadMetaAction<...> | PayloadMetaAction<...> | PayloadAction<...>>'.
  Il tipo 'unknown' non è assegnabile al tipo 'RouterAction | PayloadAction<"ADD_TODO", Todo> | PayloadAction<"REMOVE_TODO", string> | PayloadMetaAction<"LOAD_TODOS_REQUEST", unknown, unknown> | PayloadAction<"LOAD_TODOS_SUCCESS", Todo[]> | PayloadAction<...> | PayloadMetaAction<...> | PayloadMetaAction<...> | PayloadAction<...>'.
    Type '{}' is missing the following properties from type 'PayloadAction<"SAVE_TODOS_FAILURE", string>': type, payloadts(2322)
index.d.ts(36, 26): The expected type comes from the return type of this signature.

Expected behavior

Typescript compiles since the return type is correct

Suggested solution(s)

Project Dependencies



[1]: https://github.com/piotrwitek/typesafe-actions#compatibility-notes
[2]: https://github.com/piotrwitek/typesafe-actions#migration-guides
EmmanueleVilla commented 4 years ago

Update: it seems that using "switchMap" it's what's causing the error.

As per the issue description, this doesn't work:

export const test1: Epic<RootAction, RootAction, RootState> = (action$, _state$, {}) => {
  return action$.pipe(
    filter(isActionOf(homeActions.homeLoadListingAction.request)),
    switchMap(_action => of(homeActions.homeLoadSectionAction.success([]))),
  );
};

I've tried to remove the filter and it still doesn't work:

export const test2: Epic<RootAction, RootAction, RootState> = (action$, _state$, {}) => {
  return action$.pipe(
    switchMap(_action => of(homeActions.homeLoadSectionAction.success([]))),
  );
};

But if I remove the switchMap, it works:

export const test1: Epic<RootAction, RootAction, RootState> = (action$, _state$, {}) => {
  return of(homeActions.homeLoadSectionAction.success([]));
};

So the return type seems correct

EmmanueleVilla commented 4 years ago

Update: I've changed the tsconfig from

"target": "es5"

to

"target": "esnext"

and now it works. Do you know why it doesn't work on es5? Should it?