The recommended usage of redux-loop's Cmd.run
lacks type safety, which is
problematic when a project relies on TypeScript.
Firstly, the args
are typed any
, and will not error when they don't match
the arguments of the function to be run.
Second, the arguments to successActionCreator
don't need to match the
return type of the function to be run.
Replace usages of Cmd.run
with typesafeCmdRun
to get type safety.
If you need to pass arguments into the function, wrap it in a lambda expression.
function typesafeCmdRun<T>(
f: () => Promise<T>,
failActionCreator: (e: Error) => RootAction,
successActionCreator: (args: T) => RootAction,
): RunCmd<RootAction> {
return Cmd.run<RootAction>(f, {
failActionCreator,
successActionCreator,
})
}
// ...
case 'INIT':
return loop<Model, RootAction>(
state,
Cmd.batch<RootAction>([
Cmd.run<RootAction>(fetchStats, {
args: [state.clientSettings],
failActionCreator: dashboardDataFetchFailed,
successActionCreator: dashboardDataFetchSuccessful,
}),
Cmd.run<RootAction>typesafeCmdRun(fetchDomainGroups, {
args: [],
failActionCreator: domainGroupFetchFailed,
successActionCreator: domainGroupFetchSuccessful,
),
]),
)
// ...
// ...
case 'INIT':
return loop<Model, RootAction>(
state,
Cmd.batch<RootAction>([
typesafeCmdRun(
() => fetchStats(state.clientSettings),
dashboardDataFetchFailed,
dashboardDataFetchSuccessful,
),
typesafeCmdRun(
fetchDomainGroups,
domainGroupFetchFailed,
domainGroupFetchSuccessful,
),
]),
)
// ...