Skip to content

Commit 282e859

Browse files
committed
feat(hooks): mutation error typing
1 parent 1ae60dd commit 282e859

13 files changed

+194
-77
lines changed

docs/useCreate.md

+14
Original file line numberDiff line numberDiff line change
@@ -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

+14
Original file line numberDiff line numberDiff line change
@@ -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

+14
Original file line numberDiff line numberDiff line change
@@ -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

+14
Original file line numberDiff line numberDiff line change
@@ -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

+14
Original file line numberDiff line numberDiff line change
@@ -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,
@@ -58,11 +61,10 @@ export const useCreateController = <RecordType extends RaRecord = RaRecord>(
5861
const recordToUse = record ?? getRecordFromLocation(location) ?? undefined;
5962
const { onSuccess, onError, ...otherMutationOptions } = mutationOptions;
6063

61-
const [create, { isLoading: saving }] = useCreate<RecordType>(
62-
resource,
63-
undefined,
64-
otherMutationOptions
65-
);
64+
const [create, { isLoading: saving }] = useCreate<
65+
RecordType,
66+
MutationOptionsError
67+
>(resource, undefined, otherMutationOptions);
6668

6769
const save = useCallback(
6870
(
@@ -155,14 +157,17 @@ export const useCreateController = <RecordType extends RaRecord = RaRecord>(
155157
};
156158
};
157159

158-
export interface CreateControllerProps<RecordType extends RaRecord = RaRecord> {
160+
export interface CreateControllerProps<
161+
RecordType extends RaRecord = RaRecord,
162+
MutationOptionsError = unknown
163+
> {
159164
disableAuthentication?: boolean;
160165
record?: Partial<RecordType>;
161166
redirect?: RedirectionSideEffect;
162167
resource?: string;
163168
mutationOptions?: UseMutationOptions<
164169
RecordType,
165-
unknown,
170+
MutationOptionsError,
166171
CreateParams<RecordType>
167172
>;
168173
transform?: TransformData;

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

+14-9
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ import { SaveHandler } from '../saveContext';
4343
* return <EditView {...controllerProps} {...props} />;
4444
* }
4545
*/
46-
export const useEditController = <RecordType extends RaRecord = any>(
47-
props: EditControllerProps<RecordType> = {}
46+
export const useEditController = <
47+
RecordType extends RaRecord = any,
48+
MutationOptionsError = unknown
49+
>(
50+
props: EditControllerProps<RecordType, MutationOptionsError> = {}
4851
): EditControllerResult<RecordType> => {
4952
const {
5053
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
(
@@ -198,13 +200,16 @@ export const useEditController = <RecordType extends RaRecord = any>(
198200
};
199201
};
200202

201-
export interface EditControllerProps<RecordType extends RaRecord = any> {
203+
export interface EditControllerProps<
204+
RecordType extends RaRecord = any,
205+
MutationOptionsError = unknown
206+
> {
202207
disableAuthentication?: boolean;
203208
id?: RecordType['id'];
204209
mutationMode?: MutationMode;
205210
mutationOptions?: UseMutationOptions<
206211
RecordType,
207-
unknown,
212+
MutationOptionsError,
208213
UpdateParams<RecordType>
209214
>;
210215
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)