Search code examples
typescriptreact-hookshookapollo-clientreact-apollo-hooks

How to use Apollo Client custom hooks with TypeScript?


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?


Solution

  • 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 }
      ];
    };