Skip to content

Commit a85d306

Browse files
authored
Merge pull request #7698 from pocivaneuh/feat/use-mutation-error-typing
feat(hooks): mutation error typing
2 parents d06a297 + 853d90d commit a85d306

13 files changed

+199
-82
lines changed

docs/useCreate.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: "useCreate"
55

66
# `useCreate`
77

8-
This hook allows to call `dataProvider.create()` when the callback is executed.
8+
This hook allows to call `dataProvider.create()` when the callback is executed.
99

1010
```jsx
1111
// syntax
@@ -55,3 +55,17 @@ const LikeButton = ({ record }) => {
5555
return <button disabled={isLoading} onClick={handleClick}>Like</button>;
5656
};
5757
```
58+
59+
**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:
60+
61+
```tsx
62+
useCreate<Product, Error>(undefined, undefined, {
63+
onError: (error) => {
64+
// error is an instance of Error.
65+
},
66+
onSettled: (data, error) => {
67+
// data is an instance of Product.
68+
// error is an instance of Error.
69+
},
70+
})
71+
```

docs/useDelete.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: "useDelete"
55

66
# `useDelete`
77

8-
This hook allows calling `dataProvider.delete()` when the callback is executed and deleting a single record based on its `id`.
8+
This hook allows calling `dataProvider.delete()` when the callback is executed and deleting a single record based on its `id`.
99

1010
```jsx
1111
// syntax
@@ -59,3 +59,17 @@ const DeleteButton = ({ record }) => {
5959
return <button disabled={isLoading} onClick={handleClick}>Delete</button>;
6060
};
6161
```
62+
63+
**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:
64+
65+
```tsx
66+
useDelete<Product, Error>(undefined, undefined, {
67+
onError: (error) => {
68+
// error is an instance of Error.
69+
},
70+
onSettled: (data, error) => {
71+
// data is an instance of Product.
72+
// error is an instance of Error.
73+
},
74+
})
75+
```

docs/useDeleteMany.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: "useDeleteMany"
55

66
# `useDeleteMany`
77

8-
This hook allows to call `dataProvider.deleteMany()` when the callback is executed, and delete an array of records based on their `ids`.
8+
This hook allows to call `dataProvider.deleteMany()` when the callback is executed, and delete an array of records based on their `ids`.
99

1010
```jsx
1111
// syntax
@@ -59,3 +59,17 @@ const BulkDeletePostsButton = ({ selectedIds }) => {
5959
return <button disabled={isLoading} onClick={handleClick}>Delete selected posts</button>;
6060
};
6161
```
62+
63+
**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:
64+
65+
```tsx
66+
useDeleteMany<Product, Error>(undefined, undefined, {
67+
onError: (error) => {
68+
// error is an instance of Error.
69+
},
70+
onSettled: (data, error) => {
71+
// data is an instance of Product.
72+
// error is an instance of Error.
73+
},
74+
})
75+
```

docs/useUpdate.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: "useUpdate"
55

66
# `useUpdate`
77

8-
This hook allows to call `dataProvider.update()` when the callback is executed, and update a single record based on its `id` and a `data` argument.
8+
This hook allows to call `dataProvider.update()` when the callback is executed, and update a single record based on its `id` and a `data` argument.
99

1010
```jsx
1111
// syntax
@@ -61,3 +61,17 @@ const IncreaseLikeButton = ({ record }) => {
6161
return <button disabled={isLoading} onClick={handleClick}>Like</button>;
6262
};
6363
```
64+
65+
**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:
66+
67+
```tsx
68+
useUpdate<Product, Error>(undefined, undefined, {
69+
onError: (error) => {
70+
// error is an instance of Error.
71+
},
72+
onSettled: (data, error) => {
73+
// data is an instance of Product.
74+
// error is an instance of Error.
75+
},
76+
})
77+
```

docs/useUpdateMany.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: "useUpdateMany"
55

66
# `useUpdateMany`
77

8-
This hook allows to call `dataProvider.updateMany()` when the callback is executed, and update an array of records based on their `ids` and a `data` argument.
8+
This hook allows to call `dataProvider.updateMany()` when the callback is executed, and update an array of records based on their `ids` and a `data` argument.
99

1010

1111
```jsx
@@ -60,3 +60,17 @@ const BulkResetViewsButton = ({ selectedIds }) => {
6060
return <button disabled={isLoading} onClick={handleClick}>Reset views</button>;
6161
};
6262
```
63+
64+
**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:
65+
66+
```tsx
67+
useUpdateMany<Product, Error>(undefined, undefined, {
68+
onError: (error) => {
69+
// error is an instance of Error.
70+
},
71+
onSettled: (data, error) => {
72+
// data is an instance of Product.
73+
// error is an instance of Error.
74+
},
75+
})
76+
```

packages/ra-core/src/controller/create/useCreateController.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,11 @@ import {
3535
* return <CreateView {...controllerProps} {...props} />;
3636
* }
3737
*/
38-
export const useCreateController = <RecordType extends RaRecord = RaRecord>(
39-
props: CreateControllerProps<RecordType> = {}
38+
export const useCreateController = <
39+
RecordType extends RaRecord = RaRecord,
40+
MutationOptionsError = unknown
41+
>(
42+
props: CreateControllerProps<RecordType, MutationOptionsError> = {}
4043
): CreateControllerResult<RecordType> => {
4144
const {
4245
disableAuthentication,
@@ -63,11 +66,10 @@ export const useCreateController = <RecordType extends RaRecord = RaRecord>(
6366
unregisterMutationMiddleware,
6467
} = useMutationMiddlewares();
6568

66-
const [create, { isLoading: saving }] = useCreate<RecordType>(
67-
resource,
68-
undefined,
69-
otherMutationOptions
70-
);
69+
const [create, { isLoading: saving }] = useCreate<
70+
RecordType,
71+
MutationOptionsError
72+
>(resource, undefined, otherMutationOptions);
7173

7274
const save = useCallback(
7375
(
@@ -166,7 +168,10 @@ export const useCreateController = <RecordType extends RaRecord = RaRecord>(
166168
};
167169
};
168170

169-
export interface CreateControllerProps<RecordType extends RaRecord = RaRecord> {
171+
export interface CreateControllerProps<
172+
RecordType extends RaRecord = RaRecord,
173+
MutationOptionsError = unknown
174+
> {
170175
disableAuthentication?: boolean;
171176
hasEdit?: boolean;
172177
hasShow?: boolean;
@@ -175,7 +180,7 @@ export interface CreateControllerProps<RecordType extends RaRecord = RaRecord> {
175180
resource?: string;
176181
mutationOptions?: UseMutationOptions<
177182
RecordType,
178-
unknown,
183+
MutationOptionsError,
179184
UseCreateMutateParams<RecordType>
180185
>;
181186
transform?: TransformData;

packages/ra-core/src/controller/edit/useEditController.ts

+14-9
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ import { SaveContextValue, useMutationMiddlewares } from '../saveContext';
3939
* return <EditView {...controllerProps} {...props} />;
4040
* }
4141
*/
42-
export const useEditController = <RecordType extends RaRecord = any>(
43-
props: EditControllerProps<RecordType> = {}
42+
export const useEditController = <
43+
RecordType extends RaRecord = any,
44+
MutationOptionsError = unknown
45+
>(
46+
props: EditControllerProps<RecordType, MutationOptionsError> = {}
4447
): EditControllerResult<RecordType> => {
4548
const {
4649
disableAuthentication,
@@ -101,11 +104,10 @@ export const useEditController = <RecordType extends RaRecord = any>(
101104

102105
const recordCached = { id, previousData: record };
103106

104-
const [update, { isLoading: saving }] = useUpdate<RecordType>(
105-
resource,
106-
recordCached,
107-
{ ...otherMutationOptions, mutationMode }
108-
);
107+
const [update, { isLoading: saving }] = useUpdate<
108+
RecordType,
109+
MutationOptionsError
110+
>(resource, recordCached, { ...otherMutationOptions, mutationMode });
109111

110112
const save = useCallback(
111113
(
@@ -211,13 +213,16 @@ export const useEditController = <RecordType extends RaRecord = any>(
211213
};
212214
};
213215

214-
export interface EditControllerProps<RecordType extends RaRecord = any> {
216+
export interface EditControllerProps<
217+
RecordType extends RaRecord = any,
218+
MutationOptionsError = unknown
219+
> {
215220
disableAuthentication?: boolean;
216221
id?: RecordType['id'];
217222
mutationMode?: MutationMode;
218223
mutationOptions?: UseMutationOptions<
219224
RecordType,
220-
unknown,
225+
MutationOptionsError,
221226
UseUpdateMutateParams<RecordType>
222227
>;
223228
queryOptions?: UseQueryOptions<RecordType>;

packages/ra-core/src/dataProvider/useCreate.ts

+15-10
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,14 @@ import { RaRecord, CreateParams } from '../types';
6666
* const [create, { data }] = useCreate<Product>('products', { data: product });
6767
* \-- data is Product
6868
*/
69-
export const useCreate = <RecordType extends RaRecord = any>(
69+
export const useCreate = <
70+
RecordType extends RaRecord = any,
71+
MutationError = unknown
72+
>(
7073
resource?: string,
7174
params: Partial<CreateParams<Partial<RecordType>>> = {},
72-
options: UseCreateOptions<RecordType> = {}
73-
): UseCreateResult<RecordType> => {
75+
options: UseCreateOptions<RecordType, MutationError> = {}
76+
): UseCreateResult<RecordType, boolean, MutationError> => {
7477
const dataProvider = useDataProvider();
7578
const queryClient = useQueryClient();
7679
const paramsRef = useRef<Partial<CreateParams<Partial<RecordType>>>>(
@@ -79,7 +82,7 @@ export const useCreate = <RecordType extends RaRecord = any>(
7982

8083
const mutation = useMutation<
8184
RecordType,
82-
unknown,
85+
MutationError,
8386
Partial<UseCreateMutateParams<RecordType>>
8487
>(
8588
({
@@ -119,7 +122,7 @@ export const useCreate = <RecordType extends RaRecord = any>(
119122
callTimeParams: Partial<CreateParams<RecordType>> = {},
120123
createOptions: MutateOptions<
121124
RecordType,
122-
unknown,
125+
MutationError,
123126
Partial<UseCreateMutateParams<RecordType>>,
124127
unknown
125128
> & { returnPromise?: boolean } = {}
@@ -147,30 +150,32 @@ export interface UseCreateMutateParams<RecordType extends RaRecord = any> {
147150
}
148151

149152
export type UseCreateOptions<
150-
RecordType extends RaRecord = any
153+
RecordType extends RaRecord = any,
154+
MutationError = unknown
151155
> = UseMutationOptions<
152156
RecordType,
153-
unknown,
157+
MutationError,
154158
Partial<UseCreateMutateParams<RecordType>>
155159
>;
156160

157161
export type UseCreateResult<
158162
RecordType extends RaRecord = any,
159-
TReturnPromise extends boolean = boolean
163+
TReturnPromise extends boolean = boolean,
164+
MutationError = unknown
160165
> = [
161166
(
162167
resource?: string,
163168
params?: Partial<CreateParams<Partial<RecordType>>>,
164169
options?: MutateOptions<
165170
RecordType,
166-
unknown,
171+
MutationError,
167172
Partial<UseCreateMutateParams<RecordType>>,
168173
unknown
169174
> & { returnPromise?: TReturnPromise }
170175
) => Promise<TReturnPromise extends true ? RecordType : void>,
171176
UseMutationResult<
172177
RecordType,
173-
unknown,
178+
MutationError,
174179
Partial<UseCreateMutateParams<RecordType>>,
175180
unknown
176181
>

packages/ra-core/src/dataProvider/useDelete.ts

+19-12
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,14 @@ import { RaRecord, DeleteParams, MutationMode } from '../types';
6868
* const [delete, { data }] = useDelete<Product>('products', { id, previousData: product });
6969
* \-- data is Product
7070
*/
71-
export const useDelete = <RecordType extends RaRecord = any>(
71+
export const useDelete = <
72+
RecordType extends RaRecord = any,
73+
MutationError = unknown
74+
>(
7275
resource?: string,
7376
params: Partial<DeleteParams<RecordType>> = {},
74-
options: UseDeleteOptions<RecordType> = {}
75-
): UseDeleteResult<RecordType> => {
77+
options: UseDeleteOptions<RecordType, MutationError> = {}
78+
): UseDeleteResult<RecordType, MutationError> => {
7679
const dataProvider = useDataProvider();
7780
const queryClient = useQueryClient();
7881
const { id, previousData } = params;
@@ -141,7 +144,7 @@ export const useDelete = <RecordType extends RaRecord = any>(
141144

142145
const mutation = useMutation<
143146
RecordType,
144-
unknown,
147+
MutationError,
145148
Partial<UseDeleteMutateParams<RecordType>>
146149
>(
147150
({
@@ -176,7 +179,7 @@ export const useDelete = <RecordType extends RaRecord = any>(
176179
}
177180
},
178181
onError: (
179-
error: unknown,
182+
error: MutationError,
180183
variables: Partial<UseDeleteMutateParams<RecordType>> = {},
181184
context: { snapshot: Snapshot }
182185
) => {
@@ -227,7 +230,7 @@ export const useDelete = <RecordType extends RaRecord = any>(
227230
},
228231
onSettled: (
229232
data: RecordType,
230-
error: unknown,
233+
error: MutationError,
231234
variables: Partial<UseDeleteMutateParams<RecordType>> = {},
232235
context: { snapshot: Snapshot }
233236
) => {
@@ -258,7 +261,7 @@ export const useDelete = <RecordType extends RaRecord = any>(
258261
callTimeParams: Partial<DeleteParams<RecordType>> = {},
259262
updateOptions: MutateOptions<
260263
RecordType,
261-
unknown,
264+
MutationError,
262265
Partial<UseDeleteMutateParams<RecordType>>,
263266
unknown
264267
> & { mutationMode?: MutationMode } = {}
@@ -388,27 +391,31 @@ export interface UseDeleteMutateParams<RecordType extends RaRecord = any> {
388391
}
389392

390393
export type UseDeleteOptions<
391-
RecordType extends RaRecord = any
394+
RecordType extends RaRecord = any,
395+
MutationError = unknown
392396
> = UseMutationOptions<
393397
RecordType,
394-
unknown,
398+
MutationError,
395399
Partial<UseDeleteMutateParams<RecordType>>
396400
> & { mutationMode?: MutationMode };
397401

398-
export type UseDeleteResult<RecordType extends RaRecord = any> = [
402+
export type UseDeleteResult<
403+
RecordType extends RaRecord = any,
404+
MutationError = unknown
405+
> = [
399406
(
400407
resource?: string,
401408
params?: Partial<DeleteParams<RecordType>>,
402409
options?: MutateOptions<
403410
RecordType,
404-
unknown,
411+
MutationError,
405412
Partial<UseDeleteMutateParams<RecordType>>,
406413
unknown
407414
> & { mutationMode?: MutationMode }
408415
) => Promise<void>,
409416
UseMutationResult<
410417
RecordType,
411-
unknown,
418+
MutationError,
412419
Partial<DeleteParams<RecordType> & { resource?: string }>,
413420
unknown
414421
>

0 commit comments

Comments
 (0)