Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TypeScript] Fix cannot specify the error type in mutation hooks #7698

Merged
merged 2 commits into from
May 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion docs/useCreate.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "useCreate"

# `useCreate`

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

```jsx
// syntax
Expand Down Expand Up @@ -55,3 +55,17 @@ const LikeButton = ({ record }) => {
return <button disabled={isLoading} onClick={handleClick}>Like</button>;
};
```

**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:

```tsx
useCreate<Product, Error>(undefined, undefined, {
onError: (error) => {
// error is an instance of Error.
},
onSettled: (data, error) => {
// data is an instance of Product.
// error is an instance of Error.
},
})
```
16 changes: 15 additions & 1 deletion docs/useDelete.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "useDelete"

# `useDelete`

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

```jsx
// syntax
Expand Down Expand Up @@ -59,3 +59,17 @@ const DeleteButton = ({ record }) => {
return <button disabled={isLoading} onClick={handleClick}>Delete</button>;
};
```

**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:

```tsx
useDelete<Product, Error>(undefined, undefined, {
onError: (error) => {
// error is an instance of Error.
},
onSettled: (data, error) => {
// data is an instance of Product.
// error is an instance of Error.
},
})
```
16 changes: 15 additions & 1 deletion docs/useDeleteMany.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "useDeleteMany"

# `useDeleteMany`

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

```jsx
// syntax
Expand Down Expand Up @@ -59,3 +59,17 @@ const BulkDeletePostsButton = ({ selectedIds }) => {
return <button disabled={isLoading} onClick={handleClick}>Delete selected posts</button>;
};
```

**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:

```tsx
useDeleteMany<Product, Error>(undefined, undefined, {
onError: (error) => {
// error is an instance of Error.
},
onSettled: (data, error) => {
// data is an instance of Product.
// error is an instance of Error.
},
})
```
16 changes: 15 additions & 1 deletion docs/useUpdate.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "useUpdate"

# `useUpdate`

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.
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.

```jsx
// syntax
Expand Down Expand Up @@ -61,3 +61,17 @@ const IncreaseLikeButton = ({ record }) => {
return <button disabled={isLoading} onClick={handleClick}>Like</button>;
};
```

**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:

```tsx
useUpdate<Product, Error>(undefined, undefined, {
onError: (error) => {
// error is an instance of Error.
},
onSettled: (data, error) => {
// data is an instance of Product.
// error is an instance of Error.
},
})
```
16 changes: 15 additions & 1 deletion docs/useUpdateMany.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ title: "useUpdateMany"

# `useUpdateMany`

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.
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.


```jsx
Expand Down Expand Up @@ -60,3 +60,17 @@ const BulkResetViewsButton = ({ selectedIds }) => {
return <button disabled={isLoading} onClick={handleClick}>Reset views</button>;
};
```

**Tip**: If you use TypeScript, you can specify the record and error types for more type safety:

```tsx
useUpdateMany<Product, Error>(undefined, undefined, {
onError: (error) => {
// error is an instance of Error.
},
onSettled: (data, error) => {
// data is an instance of Product.
// error is an instance of Error.
},
})
```
23 changes: 14 additions & 9 deletions packages/ra-core/src/controller/create/useCreateController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ import {
* return <CreateView {...controllerProps} {...props} />;
* }
*/
export const useCreateController = <RecordType extends RaRecord = RaRecord>(
props: CreateControllerProps<RecordType> = {}
export const useCreateController = <
RecordType extends RaRecord = RaRecord,
MutationOptionsError = unknown
>(
props: CreateControllerProps<RecordType, MutationOptionsError> = {}
): CreateControllerResult<RecordType> => {
const {
disableAuthentication,
Expand All @@ -63,11 +66,10 @@ export const useCreateController = <RecordType extends RaRecord = RaRecord>(
unregisterMutationMiddleware,
} = useMutationMiddlewares();

const [create, { isLoading: saving }] = useCreate<RecordType>(
resource,
undefined,
otherMutationOptions
);
const [create, { isLoading: saving }] = useCreate<
RecordType,
MutationOptionsError
>(resource, undefined, otherMutationOptions);

const save = useCallback(
(
Expand Down Expand Up @@ -166,7 +168,10 @@ export const useCreateController = <RecordType extends RaRecord = RaRecord>(
};
};

export interface CreateControllerProps<RecordType extends RaRecord = RaRecord> {
export interface CreateControllerProps<
RecordType extends RaRecord = RaRecord,
MutationOptionsError = unknown
> {
disableAuthentication?: boolean;
hasEdit?: boolean;
hasShow?: boolean;
Expand All @@ -175,7 +180,7 @@ export interface CreateControllerProps<RecordType extends RaRecord = RaRecord> {
resource?: string;
mutationOptions?: UseMutationOptions<
RecordType,
unknown,
MutationOptionsError,
UseCreateMutateParams<RecordType>
>;
transform?: TransformData;
Expand Down
23 changes: 14 additions & 9 deletions packages/ra-core/src/controller/edit/useEditController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,11 @@ import { SaveContextValue, useMutationMiddlewares } from '../saveContext';
* return <EditView {...controllerProps} {...props} />;
* }
*/
export const useEditController = <RecordType extends RaRecord = any>(
props: EditControllerProps<RecordType> = {}
export const useEditController = <
RecordType extends RaRecord = any,
MutationOptionsError = unknown
>(
props: EditControllerProps<RecordType, MutationOptionsError> = {}
): EditControllerResult<RecordType> => {
const {
disableAuthentication,
Expand Down Expand Up @@ -101,11 +104,10 @@ export const useEditController = <RecordType extends RaRecord = any>(

const recordCached = { id, previousData: record };

const [update, { isLoading: saving }] = useUpdate<RecordType>(
resource,
recordCached,
{ ...otherMutationOptions, mutationMode }
);
const [update, { isLoading: saving }] = useUpdate<
RecordType,
MutationOptionsError
>(resource, recordCached, { ...otherMutationOptions, mutationMode });

const save = useCallback(
(
Expand Down Expand Up @@ -211,13 +213,16 @@ export const useEditController = <RecordType extends RaRecord = any>(
};
};

export interface EditControllerProps<RecordType extends RaRecord = any> {
export interface EditControllerProps<
RecordType extends RaRecord = any,
MutationOptionsError = unknown
> {
disableAuthentication?: boolean;
id?: RecordType['id'];
mutationMode?: MutationMode;
mutationOptions?: UseMutationOptions<
RecordType,
unknown,
MutationOptionsError,
UseUpdateMutateParams<RecordType>
>;
queryOptions?: UseQueryOptions<RecordType>;
Expand Down
25 changes: 15 additions & 10 deletions packages/ra-core/src/dataProvider/useCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,14 @@ import { RaRecord, CreateParams } from '../types';
* const [create, { data }] = useCreate<Product>('products', { data: product });
* \-- data is Product
*/
export const useCreate = <RecordType extends RaRecord = any>(
export const useCreate = <
RecordType extends RaRecord = any,
MutationError = unknown
>(
resource?: string,
params: Partial<CreateParams<Partial<RecordType>>> = {},
options: UseCreateOptions<RecordType> = {}
): UseCreateResult<RecordType> => {
options: UseCreateOptions<RecordType, MutationError> = {}
): UseCreateResult<RecordType, boolean, MutationError> => {
const dataProvider = useDataProvider();
const queryClient = useQueryClient();
const paramsRef = useRef<Partial<CreateParams<Partial<RecordType>>>>(
Expand All @@ -79,7 +82,7 @@ export const useCreate = <RecordType extends RaRecord = any>(

const mutation = useMutation<
RecordType,
unknown,
MutationError,
Partial<UseCreateMutateParams<RecordType>>
>(
({
Expand Down Expand Up @@ -119,7 +122,7 @@ export const useCreate = <RecordType extends RaRecord = any>(
callTimeParams: Partial<CreateParams<RecordType>> = {},
createOptions: MutateOptions<
RecordType,
unknown,
MutationError,
Partial<UseCreateMutateParams<RecordType>>,
unknown
> & { returnPromise?: boolean } = {}
Expand Down Expand Up @@ -147,30 +150,32 @@ export interface UseCreateMutateParams<RecordType extends RaRecord = any> {
}

export type UseCreateOptions<
RecordType extends RaRecord = any
RecordType extends RaRecord = any,
MutationError = unknown
> = UseMutationOptions<
RecordType,
unknown,
MutationError,
Partial<UseCreateMutateParams<RecordType>>
>;

export type UseCreateResult<
RecordType extends RaRecord = any,
TReturnPromise extends boolean = boolean
TReturnPromise extends boolean = boolean,
MutationError = unknown
> = [
(
resource?: string,
params?: Partial<CreateParams<Partial<RecordType>>>,
options?: MutateOptions<
RecordType,
unknown,
MutationError,
Partial<UseCreateMutateParams<RecordType>>,
unknown
> & { returnPromise?: TReturnPromise }
) => Promise<TReturnPromise extends true ? RecordType : void>,
UseMutationResult<
RecordType,
unknown,
MutationError,
Partial<UseCreateMutateParams<RecordType>>,
unknown
>
Expand Down
31 changes: 19 additions & 12 deletions packages/ra-core/src/dataProvider/useDelete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,14 @@ import { RaRecord, DeleteParams, MutationMode } from '../types';
* const [delete, { data }] = useDelete<Product>('products', { id, previousData: product });
* \-- data is Product
*/
export const useDelete = <RecordType extends RaRecord = any>(
export const useDelete = <
RecordType extends RaRecord = any,
MutationError = unknown
>(
resource?: string,
params: Partial<DeleteParams<RecordType>> = {},
options: UseDeleteOptions<RecordType> = {}
): UseDeleteResult<RecordType> => {
options: UseDeleteOptions<RecordType, MutationError> = {}
): UseDeleteResult<RecordType, MutationError> => {
const dataProvider = useDataProvider();
const queryClient = useQueryClient();
const { id, previousData } = params;
Expand Down Expand Up @@ -141,7 +144,7 @@ export const useDelete = <RecordType extends RaRecord = any>(

const mutation = useMutation<
RecordType,
unknown,
MutationError,
Partial<UseDeleteMutateParams<RecordType>>
>(
({
Expand Down Expand Up @@ -176,7 +179,7 @@ export const useDelete = <RecordType extends RaRecord = any>(
}
},
onError: (
error: unknown,
error: MutationError,
variables: Partial<UseDeleteMutateParams<RecordType>> = {},
context: { snapshot: Snapshot }
) => {
Expand Down Expand Up @@ -227,7 +230,7 @@ export const useDelete = <RecordType extends RaRecord = any>(
},
onSettled: (
data: RecordType,
error: unknown,
error: MutationError,
variables: Partial<UseDeleteMutateParams<RecordType>> = {},
context: { snapshot: Snapshot }
) => {
Expand Down Expand Up @@ -258,7 +261,7 @@ export const useDelete = <RecordType extends RaRecord = any>(
callTimeParams: Partial<DeleteParams<RecordType>> = {},
updateOptions: MutateOptions<
RecordType,
unknown,
MutationError,
Partial<UseDeleteMutateParams<RecordType>>,
unknown
> & { mutationMode?: MutationMode } = {}
Expand Down Expand Up @@ -388,27 +391,31 @@ export interface UseDeleteMutateParams<RecordType extends RaRecord = any> {
}

export type UseDeleteOptions<
RecordType extends RaRecord = any
RecordType extends RaRecord = any,
MutationError = unknown
> = UseMutationOptions<
RecordType,
unknown,
MutationError,
Partial<UseDeleteMutateParams<RecordType>>
> & { mutationMode?: MutationMode };

export type UseDeleteResult<RecordType extends RaRecord = any> = [
export type UseDeleteResult<
RecordType extends RaRecord = any,
MutationError = unknown
> = [
(
resource?: string,
params?: Partial<DeleteParams<RecordType>>,
options?: MutateOptions<
RecordType,
unknown,
MutationError,
Partial<UseDeleteMutateParams<RecordType>>,
unknown
> & { mutationMode?: MutationMode }
) => Promise<void>,
UseMutationResult<
RecordType,
unknown,
MutationError,
Partial<DeleteParams<RecordType> & { resource?: string }>,
unknown
>
Expand Down
Loading