Improve `createdataLoadingThunk` (#30778)

This commit is contained in:
Renaud Chaput 2024-06-20 13:42:10 +02:00 committed by GitHub
parent 7889e983fb
commit 27529247b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 25 additions and 11 deletions

View File

@ -82,13 +82,19 @@ export function createThunk<Arg = void, Returned = void>(
const discardLoadDataInPayload = Symbol('discardLoadDataInPayload'); const discardLoadDataInPayload = Symbol('discardLoadDataInPayload');
type DiscardLoadData = typeof discardLoadDataInPayload; type DiscardLoadData = typeof discardLoadDataInPayload;
type OnData<LoadDataResult, ReturnedData> = ( type OnData<ActionArg, LoadDataResult, ReturnedData> = (
data: LoadDataResult, data: LoadDataResult,
api: AppThunkApi & { api: AppThunkApi & {
actionArg: ActionArg;
discardLoadData: DiscardLoadData; discardLoadData: DiscardLoadData;
}, },
) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>; ) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>;
type LoadData<Args, LoadDataResult> = (
args: Args,
api: AppThunkApi,
) => Promise<LoadDataResult>;
type ArgsType = Record<string, unknown> | undefined; type ArgsType = Record<string, unknown> | undefined;
// Overload when there is no `onData` method, the payload is the `onData` result // Overload when there is no `onData` method, the payload is the `onData` result
@ -101,18 +107,18 @@ export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty // Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>( export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
name: string, name: string,
loadData: (args: Args) => Promise<LoadDataResult>, loadData: LoadData<Args, LoadDataResult>,
onDataOrThunkOptions?: onDataOrThunkOptions?:
| AppThunkOptions | AppThunkOptions
| OnData<LoadDataResult, DiscardLoadData>, | OnData<Args, LoadDataResult, DiscardLoadData>,
thunkOptions?: AppThunkOptions, thunkOptions?: AppThunkOptions,
): ReturnType<typeof createThunk<Args, void>>; ): ReturnType<typeof createThunk<Args, void>>;
// Overload when the `onData` method returns nothing, then the mayload is the `onData` result // Overload when the `onData` method returns nothing, then the mayload is the `onData` result
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>( export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
name: string, name: string,
loadData: (args: Args) => Promise<LoadDataResult>, loadData: LoadData<Args, LoadDataResult>,
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, void>, onDataOrThunkOptions?: AppThunkOptions | OnData<Args, LoadDataResult, void>,
thunkOptions?: AppThunkOptions, thunkOptions?: AppThunkOptions,
): ReturnType<typeof createThunk<Args, LoadDataResult>>; ): ReturnType<typeof createThunk<Args, LoadDataResult>>;
@ -123,8 +129,10 @@ export function createDataLoadingThunk<
Returned, Returned,
>( >(
name: string, name: string,
loadData: (args: Args) => Promise<LoadDataResult>, loadData: LoadData<Args, LoadDataResult>,
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, Returned>, onDataOrThunkOptions?:
| AppThunkOptions
| OnData<Args, LoadDataResult, Returned>,
thunkOptions?: AppThunkOptions, thunkOptions?: AppThunkOptions,
): ReturnType<typeof createThunk<Args, Returned>>; ): ReturnType<typeof createThunk<Args, Returned>>;
@ -159,11 +167,13 @@ export function createDataLoadingThunk<
Returned, Returned,
>( >(
name: string, name: string,
loadData: (args: Args) => Promise<LoadDataResult>, loadData: LoadData<Args, LoadDataResult>,
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, Returned>, onDataOrThunkOptions?:
| AppThunkOptions
| OnData<Args, LoadDataResult, Returned>,
maybeThunkOptions?: AppThunkOptions, maybeThunkOptions?: AppThunkOptions,
) { ) {
let onData: OnData<LoadDataResult, Returned> | undefined; let onData: OnData<Args, LoadDataResult, Returned> | undefined;
let thunkOptions: AppThunkOptions | undefined; let thunkOptions: AppThunkOptions | undefined;
if (typeof onDataOrThunkOptions === 'function') onData = onDataOrThunkOptions; if (typeof onDataOrThunkOptions === 'function') onData = onDataOrThunkOptions;
@ -177,7 +187,10 @@ export function createDataLoadingThunk<
return createThunk<Args, Returned>( return createThunk<Args, Returned>(
name, name,
async (arg, { getState, dispatch }) => { async (arg, { getState, dispatch }) => {
const data = await loadData(arg); const data = await loadData(arg, {
dispatch,
getState,
});
if (!onData) return data as Returned; if (!onData) return data as Returned;
@ -185,6 +198,7 @@ export function createDataLoadingThunk<
dispatch, dispatch,
getState, getState,
discardLoadData: discardLoadDataInPayload, discardLoadData: discardLoadDataInPayload,
actionArg: arg,
}); });
// if there is no return in `onData`, we return the `onData` result // if there is no return in `onData`, we return the `onData` result