Improve type safety of `reducerBase.ts`
The reducer
function's typing in the reducerBase.ts
file could be improved, by enforcing that for example for case del?.failure
only the property error
can be accessed on action
, and for case del?.success
only requestArgs
and response
can be accessed, while for case del?.request
nothing can be accessed on action
with the corresponding types.
In order to implement this, the following feature on TypeScript is necessary: https://github.com/microsoft/TypeScript/issues/46045
Some of the code I wrote which could be reused when the TypeScript feature is implemented to implement it in reducerBase.ts
:
export type ApiAction<RequestParams extends object, ResponseType> =
| ({
type: `${string}_REQUEST`;
} & RequestParams)
| {
type: `${string}_SUCCESS`;
requestArgs: RequestParams;
response: ResponseType;
}
| {
type: `${string}_FAILURE`;
error: unknown;
};
export type ExtractRequestParams<P> = P extends ActionType<
infer RequestParams,
never
>
? RequestParams
: never;
export type ExtractResponseType<P> = P extends ActionType<
never,
infer ResponseType
>
? ResponseType
: never;
export type ApiAction<
A extends ActionType<RequestParams, ResponseType>,
// eslint-disable-next-line @typescript-eslint/ban-types
RequestParams extends object = ExtractRequestParams<A>,
ResponseType = ExtractResponseType<A>
> =
| {
type: `${A['request']}`;
}
| {
type: `${A['success']}`;
requestArgs: RequestParams;
response: ResponseType;
}
| {
type: `${A['failure']}`;
error: unknown;
};
export type GetAllReduxActions<T> = T extends (
state: any,
actions: infer Actions,
...args: any[]
) => any
? // omit empty objects like `{}`
keyof Actions extends []
? never
: Actions
: T extends Record<string, infer Values>
? GetAllReduxActions<Values>
: never;
export type AllReduxActions = GetAllReduxActions<typeof reducers>;
Edited by François Martin