Closed StrikeAgainst closed 4 months ago
This is because the return value of useQuery
uses TData
both in covariant and contravariant positions.
I'd recommend that you use TypedDocumentNode
here and then let inference take over:
const getById = <TData>(gql: TypedDocumentNode<TData>, id: string) => {
return useQuery(
gql,
computed(() => ({ id }))
)
}
and then use it like
const result = getById(MyQuery, "1")
Assuming that your queries are typed correctly (and this is probably the single most important thing to do when using GraphQL with TypeScript!), everything should be typed correctly from there on.
Your manual annotations only add inconsistencies and possibly type erasure, so I'd try to avoid those.
That said, this still breaks the rule of hooks.
What is the real value here instead of just using
const result = useQuery(gql, computed(() => ({ id })))
in your component?
Thanks for the hint, I actually forgot about the concept of contravariance, also I was not aware that there is TypedDocumentNode
.
I'm currently abstracting CRUD operations for a multitude of different entity types, where all come with their own queries and result / variables types, hence why I need some form of generic typing for - in this case - an ID-based single entity query. With your hint I got the typing down correct now though, so thanks a lot!
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. For general questions, we recommend using StackOverflow or our discord server.
Issue Description
In an effort to abstract the use of queries for various similar situations, I wrapped a query inside a function typed with an extended generic for the result
TData
. When applying this composable onto a variable typed with a more general result type, TS is giving me an error that does not make much sense to me. Below I have a condensed use case for the issue:Basically
TData
extendsRecord<string, string>
, where{ foo: string }
in theory should be assignable onto. While I can assign the return value ofgetById<{ foo: string }>
to a variable ofByIdQuery<{ foo: string }>
, I cannot apply it onto the more general type ofByIdQuery<Record<string, string>>
. In the error stack, somewhere along the line,Record<string, string>
and{ foo: string; }
are suddenly swapped then, with no indication as to why this happens.The minimal reproducible case would be this
which is also implemented in the reproduction linked below, where the error is also indicated.
Link to Reproduction
https://codesandbox.io/p/sandbox/youthful-thompson-d48qtm
@apollo/client
version3.10.1