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 98 forks source link

isOfType could accept an array of actions instead of one #85

Closed paszkowskiDamian closed 5 years ago

paszkowskiDamian commented 6 years ago

Is your feature request related to a problem?

Sometimes we have epics that listen for more than one action. It would be really cool if could preserve type-safety of isOfType while being able to filter more than one action.

Describe a solution you'd like

return action$.pipe(
    filter(isOfTypes(RELOAD_ORDERS , ORDERS_FETCH_REQUEST)),
    mergeMap(async action =>  ordersheetRepository.loadOrders(action.payload)) // action is union of RELOAD_ORDERS , ORDERS_FETCH_REQUEST actions
    ...

Who does this impact? Who is this for?

It is for TypeScript users who would like to handle multiple actions using one epic.

Describe alternatives you've considered

We could use ofType operator from redux-observable but it doesn't return proper types.

Additional context

This is my local implementaion:

export function isOfTypes<T extends string[]>(...actions: T):
  <Action extends {type: string}>(action: Action) => action is Action extends {type: Unboxed<T>} ? Action : never {
    return <Action extends {type: string}>(action: Action):
    action is Action extends {type: Unboxed<T>}
      ? Action
      : never => actions.includes(action.type);
}

This could be integrated to already existing ifOsType.

Carl-Foster commented 6 years ago

Any reason you don't use isActionOf?

piotrwitek commented 6 years ago

Hey @paszkowskiDamian, thanks for the proposal. Currently isActionOf supports an array as parameter to handle a parallel scenario. So IMO it would be just to extend isOfType API to also support an array as alternative parameter and API will stay consistent.

I agree and will integrate this change into the API.

Our test suite will also need to be extended with new API cases.

paszkowskiDamian commented 6 years ago

I've opened a new PR #86 implementing new API

paszkowskiDamian commented 6 years ago

@Carl-Foster actaully, I didn't try with isActionOf but it seems as it is not narrowing action types properly but I didn't researched it why.

action$.pipe(
    filter(isActionOf([fetchMoreAccountsFailed, fetchAccountsListFailed])),
    mergeMap(async action /*inferes as RootAction*/ => accountsRepository.doSth(action.paylod)),
IssueHuntBot commented 5 years ago

@issuehuntfest has funded $20.00 to this issue. See it on IssueHunt

IssueHuntBot commented 5 years ago

@paszkowskidamian has submitted a pull request. See it on IssueHunt

IssueHuntBot commented 5 years ago

@piotrwitek has rewarded $14.00 to @paszkowskidamian. See it on IssueHunt

piotrwitek commented 5 years ago

Resolved by #86