4

I'm trying to create a custom Apollo Client mutation hook in a TypeScript project in the following shape:

const customApolloMutation = () => {

  const [
    mutationFunction,
    { data, loading, error, ...result } // or just {...result}
  ] = useMutation(GRAPHQL_QUERY)


  return [mutationFunction,
    { data, loading, error, ...result } // or just {...result}
  ]
}

export default customApolloMutation ;

Everything seems fine, but when I import the custom hook in a different file like this:

  const [mutationFunction, {data, loading, error}] = customApolloMutation();

...all the destructured props give a TypeScript error such as Property 'loading' does not exist on type '((options?: MutationFunctionOptions<any, OperationVariables> | undefined) => Promise<FetchResult<any, Record<string, any>, Record<string, any>>>) | { ...; }'.ts(2339).

Any idea of what I'm doing wrong? Do I need to add some specific typings? Am I not destructuring/calling the hook properly?

HigoChumbo
  • 858
  • 2
  • 9
  • 23
  • 1
    try changing the return to `return useMutation(GRAPHQL_QUERY)` – WilsonPena Apr 07 '21 at 18:10
  • As in returning the whole hook without destructuring? I've done something similar (const hook=useMutation(QUERY); return hook and it works. I just had always seen people return destructured fields and though there had to be a way of doing it. –  HigoChumbo Apr 07 '21 at 18:25

1 Answers1

2

I've tried running it and it seems types are not sure if you'll return the MutationTuple as it is and instead the custom mutation hook you're creating assumes the returnValue is (options?: MutationFunctionOptions<TData, TVariables>) => Promise<FetchResult<TData>> | MutationResult[].

If you really need the destructuring, then you can make sure you add types to your mutation hook already so that you assure the user of the hook that it sens the array in a specific order.

const useApolloMutation = <TData, TVariables>(): MutationTuple<TData, TVariables> => {
  const [
    mutationFunction,
    { data, loading, error, ...result }
  ] = useMutation<TData, TVariables>(SOME_GQL);

  return [
    mutationFunction,
    { data, loading, error, ...result }
  ];
};
Leomar Amiel
  • 469
  • 3
  • 13
  • 1
    Thank you! I had tried adding the MutationTuple type but I wasn't too sure on how to use the generics. In the end I guess you have a point, I don't really need the destructuring, which simplifies things, but I'll keep that in mind in case I need a more customized hook =) –  HigoChumbo Apr 08 '21 at 04:41