graphql-code-generator: Type 'undefined' is not assignable to baseOptions

Describe the bug

When trying to update @vue/apollo-composable from 4.0.0-alpha.4 to 4.0.0-alpha.7, I’m getting the following type errors with graphql-code-generator (on argument baseOptions) for all my mutations:

Argument of type 'UseMutationOptions<DoSomethingMutation, DoSomethingMutationVariables> | undefined' is not assignable to parameter of type 'UseMutationOptionsWithVariables<DoSomethingMutation, DoSomethingMutationVariables> | ReactiveFunction<...>'.
       Type 'undefined' is not assignable to type 'UseMutationOptionsWithVariables<DoSomethingMutation, DoSomethingMutationVariables> | ReactiveFunction<...>'.
                  return VueApolloComposable.useMutation<DoSomethingMutation, DoSomethingMutationVariables>(DoSomethingDocument, baseOptions);

To Reproduce

Use the latest version of graphql-code-generator with @vue/apollo-composable 4.0.0-alpha.7 and any kind of mutation.

Config:

# ...
    plugins:
      - typescript
      - typescript-operations
      - typescript-vue-apollo

Expected behavior

Generated code triggers no compiler error.

Environment:

  • OS: Docker
  • @graphql-codegen/*: 1.13.1
  • NodeJS: 13.1.0

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (13 by maintainers)

Most upvoted comments

@NickBolles if I understand what you’re suggesting, the patch in https://github.com/vuejs/vue-apollo/pull/962 should address it. The vue-apollo maintainer has been MIA for a while, which unfortunately happens pretty often. Hopefully this will get merged soon as vue-apollo alpha is currently borked for TypeScript users.

I think the generator also needs to be updated to include the reactive function part of the useMutation defiintion too

apollo-composable

export declare function useMutation<TResult = any, TVariables extends OperationVariables = OperationVariables>(document: DocumentNode | ReactiveFunction<DocumentNode>, options?: UseMutationOptionsWithVariables<TResult, TVariables> | ReactiveFunction<UseMutationOptionsWithVariables<TResult, TVariables>>): UseMutationReturn<TResult, TVariables>;

Generated useMutation

export function useAddRecipeMutation(options: VueApolloComposable.UseMutationOptionsWithVariables<AddRecipeMutation, AddRecipeMutationVariables>) {
            return VueApolloComposable.useMutation<AddRecipeMutation, AddRecipeMutationVariables>(AddRecipeDocument, options);
          }

this part in particular

options: VueApolloComposable.UseMutationOptionsWithVariables<AddRecipeMutation, AddRecipeMutationVariables>

should probably be more like this:

options?: UseMutationOptionsWithVariables<AddRecipeMutation, AddRecipeMutationVariables> | ReactiveFunction<UseMutationOptionsWithVariables<AddRecipeMutation, AddRecipeMutationVariables>>

@iskanderbroere I investigated this further this morning.

I believe the specific issue reported here by @quentinus95 was caused by https://github.com/vuejs/vue-apollo/commit/a9d950156d1f8e89cf8ba3532936b6a09e0b776a, but that incorrect behavior is the result of an underlying incorrect assumption on my part. I believe this will be resolved after the PR for https://github.com/vuejs/vue-apollo/issues/961.

Personally, though, I think this presents an opportunity for the generator to offer a more developer-friendly API than the vue-apollo one. I would personally like to see the functions take in a single object that requires variables or not depending on the query. There are many times I want to call a query that has no variables but does have options (like for fetchPolicy) and that requires passing useThing(undefined, { options }) which just seems so clunky and y2k. It could generate something like this:

export useThingThatRequiresVariables(baseOptions: RequiredVariablesQueryOptions<x>)

export useThingWithoutVariables(baseOptions?: QueryOptions<x>)

🔥

Work partially (when operationHasNonNullableVariable)

The operand ? on variables must be set when all variables are default values, not when operationHasNonNullableVariable And in xxxxQueryVariables too. Each variable can be nullable or not, but also optional if it has a default value. If it’s not optional, we must pass it in the variables object, also if it’s Nullable :

OPTIONALS
query allOptionals($dep: String = "a string value") {
 .....
}

NON OPTIONAL : 
query allOptionals($dep: String!) {
 .....
}

Maybe we can check (in visitor) if variables has default values (like typescript-operation) and if all variables are optionals apply “?” operator on variables parameter

Look at https://graphql.org/learn/queries/#default-variables

Also, can you add (when operationHasVariables is True) :

* @variables ......

in JSDoc just upper :

* @param options that will be passed into the query,

Else : all working 👍

Fixed in 1.13.3

You’re right it only work with alpha.4, i’ll take a look making it compatible with alpha.8