I have the following code, where myAction
is a thunk:
export type ArgumentTypes<F extends Function> = F extends (
...args: infer A
) => any
? A
: never;
const dispatched = <T extends Function>(action: T, args: ArgumentTypes<T>) => {
const result = store.dispatch(action(args));
return result;
};
const res = dispatched(myAction, null);
how do I correctly type the ReturnType
of dispatched
function. res
is currently showing any
Everything else, including dispatch
is correctly typed.Is there a type in redux that can convert this?
the expected type of res
in sandbox would be Promise<string>
UPDATE:
I was able to get it down to this
const dispatched = <T extends AsyncThunk<{}, {}, {}>>(
action: T,
args: ArgumentTypes<T>,
) => {
const result = store.dispatch(action(args));
return result;
};
const res = await dispatched(myAction, null).unwrap();
it now correctly returns whatever is passed into AsyncThunk<>
but not sure how to make it generic
CodePudding user response:
For whatever reason, <T extends Function>
doesn't work with the built-in types Parameters<T>
and ReturnType<T>
. But <T extends (...args: any[]) => any>
does work.
I'm a bit confused here as to how you want to accept the arguments of the action creator. Can there be more than one argument? Do you pass multiple arguments as separate arguments or as an array? There's a difference between what you have in your question dispatched(myAction, null)
and what you have in your sandbox dispatched(myAction, ["hello world"])
. In my opinion the dispatched(myAction, "hello world")
syntax is a lot nicer, so I will do it that way.
const dispatched = <T extends (...args: any[]) => any>(
actionCreator: T,
...args: Parameters<T>
) => {
const action: ReturnType<T> = actionCreator(...args); <-- this intermediate assignment is the key.
const result = store.dispatch(action);
return result;
};
// res has type `AsyncThunkAction<string, string, AsyncThunkConfig>`
const res = dispatched(myAction, "hello world");