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

useMutation/useLazyQuery execution functions always requires full variables when using TypedDocumentNode #12100

Open
maciesielka opened this issue Oct 21, 2024 · 1 comment

Comments

@maciesielka
Copy link
Contributor

maciesielka commented Oct 21, 2024

Issue Description

The documentation for hooks like useMutation and useLazyQuery mention that there are two distinct ways to provide variables to the actual request: (1) as an option to the hook itself and (2) as an option to the query function returned by the hook. These allow variable merging such that the query function used at the call-site can override any values provided in the hook, and the docs linked above advertise this as a good way to provide defaults.

The issue I'm running into is using this with Typescript and specifically TypedDocumentNodes that strongly type the variables to the operation, because the hooks always require the fully formed Variables rather than something than might support the merging / default structure you'd expect. Some possible solutions might be something straightforward like allowing a Partial at both sites or something more involved that makes any fields provided in the hook optional in the query function.

Check the quick sketch below as well as the provided Codesandbox to see this issue in more detail:

Imagine we'd like to use the following mutation

mutation AddPerson($name: String, $title: String) {
  addPerson(name: $name, title: $title) {
    node {
      id
      name
      title
    }
  }
}

Usage of useMutation might look something like this, which creates errors in both the hook declaration and the execution usage, despite functionally working properly if you erase those errors with as any.

const [addEngineer] = useMutation(TYPED_DOCUMENT_NODE, {
  // ❌ Property 'name' is missing in type '{ title: string; }' but required in type '{ name: string; title: string; }'.
  variables: {
    title: 'Engineer'
  }
});

// ❌ Property 'title' is missing in type '{ name: string; }' but required in type '{ name: string; title: string; }'.
useEffect(() => addEngineer({ variables: { name: 'Alvin' } }), []);

The same sort of issue occurs for useLazyQuery instances where the provided operation takes variables.

Link to Reproduction

https://codesandbox.io/p/devbox/determined-elbakyan-vrsjcs?workspaceId=59bd876a-c3ad-4ffd-a783-ffc36a11e7d9

Reproduction Steps

Try it out

  1. Run the Codesandbox
  2. Type in any name and click "Add engineer"
  3. Observe that the name provided is correctly added to the list and notice that they're annotated as an Engineer

To the code

  1. Jump into the code and find two as any typecasts around useMutation and the usage of the execution function in src/index.tsx
  2. Remove both typecasts

Observe type errors despite the working functionality described in the first section above

@apollo/client version

3.11.8

@jerelmiller
Copy link
Member

Hey @maciesielka 👋

Good catch! FYI the team is away at a conference this week so we won't be able to look at this until at least next week. Thanks for raising the issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants