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

Query: Is there a way to access the AsyncAction interface for use as type of a function parameter? #211

Closed dcs3spp closed 4 years ago

dcs3spp commented 4 years ago

Hi,

Hope somebody can help with the following query, also raised on spectrum chat channel.....

I have written a generic epic that accepts an async action as a parameter, as follows:

export const genericHandler = <
  TRequestType extends string,
  TSuccessType extends string,
  TFailType extends string,
  TModel,
>(
  asyncAction: AsyncActionCreatorBuilder<
    [TRequestType, RequestPayload<TModel>],
    [TSuccessType, SuccessPayload<TModel>],
    [TFailType, FailurePayload<TModel>]
  >,
) => {
  const epic: Epic< // Is it possible to automatically generate PayloadAction types here for a generic async action argument?
    // input action types union
    | PayloadAction<
        TRequestType,
        RequestPayload<TModel>,
      >
    | PayloadAction<TSuccessType, SuccessPayload<TModel>>
    | PayloadAction<TFailType, FailurePayload<TModel>>,
    // output action types union
    | PayloadAction<
        TRequestType,
        RequestPayload<TModel>
      >
    | PayloadAction<TSuccessType, SuccessPayload<TModel>>
    | PayloadAction<TFailType, FailurePayload<TModel>>,
    RootState,
    Services
  > = (action$, state$, { apiService }) => {
      // perform middleware handling here ...
  }

The type of the aysncAction parameter is AsyncActionCreatorBuilder. In the redux-observable Epic<...> generic I manually specify the PayloadAction types for Input and Output actions in the stream.

Is there any way to automatically generate the PayloadAction types? I have tried using ActionType<typeof asyncAction> but this generates type

asyncAction: {
    request: PayloadActionCreator<TRequestType, RequestPayload<TModel>>;
    success: PayloadActionCreator<TSuccessType, SuccessPayload<TModel>>;
    failure: PayloadActionCreator<TFailType, FailPayload<TModel>>;
} 

I think this is because I am passing in the parameter type as an AsyncActionCreatorBuilder.

How can I get access to the AsyncAction interface type so that I can use it as the type for the asyncAction parameter instead of using AsyncActionCreatorBuilder? Alternatively, is there a way to automatically generate the union of PayloadAction types from the AsyncActionCreatorBuilder?

piotrwitek commented 4 years ago

This is related to the following request in that so it will result in epic instead of a reducer, but they seem to be complementary: #88

I have to close this issue because of the invalid format, but I encourage you to open a new issue using a feature request form that is following the format in #88. Then I will consider it a new feature and moreover, I'm willing to work on it having available time and resources.

dcs3spp commented 4 years ago

Hi @piotrwitek ,

Many thanks :) Have summarised using feature request here.

piotrwitek commented 4 years ago

Thanks!