apollo-client: Type inference broken in 3.8
Issue Description
In our codebase we heavily rely on type inference when using Apollo, with lots of custom hooks that look along the lines of:
const useSomethingQuery = (options?: QueryHookOptions<SomethingQuery, SomethingQueryVariables>) =>
useQuery(
gql`
query Something($args: Args) {
...
}
`,
options,
);
where the types are generated using graphql codegen.
Before updating to 3.8, this works exactly as expected–useQuery
is able to infer the types correctly from options
, which means we do not need to also add the exact same types twice.
After updating to 3.8, this inference is broken. We have to specify the types twice like so:
const useSomethingQuery = (options?: QueryHookOptions<SomethingQuery, SomethingQueryVariables>) =>
useQuery<SomethingQuery, SomethingQueryVariables>(
gql`
query Something($args: Args) {
...
}
`,
options,
);
This a very unfortunate regression that, in our case, is sufficiently annoying to prevent upgrading (which is a shame, because I was keen to give the new suspense hooks a try).
Link to Reproduction
https://
Reproduction Steps
Update to 3.8.x, observe typescript being very unhappy.
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 19 (3 by maintainers)
I’m on mobile right now and will respond with more detail in the evening, but can you give an example of such a generic hook? Are you dynamically creating Graphql queries in runtime here?
Generally: a deprecation would not mean that we would remove it anytime soon, it’s just the only visible “discouraging” indicator we have at our disposal (apart from a TS error) to indicate “you probably shouldn’t use this in most use cases” to nudge people towards more typesafe patterns where it’s possible.
@plausible-phry appreciate the detailed response and suggestions.
However, there are still various reasons to create custom hooks. Sometimes there is custom logic (omitted in the example above), but even if not we still prefer to extract the details of setting up a query/mutation to a custom hook to reduce the visual noise it otherwise introduces and to facilitate re-use.
Totally understand the rationale behind the changes here and believe the intention is correct, however I do not think it makes a great deal of sense to force consumers to only do it this way. Without looking at the code, it seems like the same outcome could be achieved by only enabling these extra checks when a consumer opt-in by choosing to use a
TypedDocumentNode
.Sometimes it isn’t even possible to use a
TypedDocumentNode
. For example, we have auseQueryAll
hook which accepts a generically-typedoptions
and auto-paginates the query:Using typed-
options
has honestly worked incredibly well for us, and presumably for many others. I hope you agree that it is worth preserving the option to do things this way!Thank you @jerelmiller. I’ve tried installing a few of the
alpha
versions and you’re exactly right–it is withalpha.7
that the type errors begin.So I’ll be sticking with
alpha.6
for now–hopefully it is only a minor tweak that is required! Perhaps we are all crazy for using a language in which writing/understanding types is much more difficult than writing/understanding code. 😂