Open jamesdh opened 7 months ago
I might take a crude hack at this, but would really appreciate any input from any of the Refine contributors!
Hey @jamesdh, I'm not very experienced with GraphQL and graphql ecosystem much but I think I understood the request here π
I think this can be done if we update the meta.gqlMutation
and meta.gqlQuery
types with union TypedDocumentNode
(from @graphql-typed-document-node/core
, compatible with gql.tada
) and TypedQueryDocumentNode
(from graphql
).
Then with couple of overloads I think we can infer types from queries π€ I couldn't find any usage of TypedQueryDocumentNode
but I guess this should be added since graphql
exports it π€ ResultOf
or VariablesOf
can be implemented for it as well but not interoperable.
// something like this
export type ResultOf<T> = T extends TypedQueryDocumentNode<infer ResultType, infer VariablesType> ? ResultType : never;
As a result I think we can achieve this:
type PostResponse = { id: BaseKey; name: string; };
const query = graphql(` ... `);
// `TData` will be inferred from `query`
- const { data } = useOne<PostResponse>({
+ const { data } = useOne({
resource: "posts",
meta: {
gqlQuery: query,
}
});
Is that what you had in mind? Do you have any more to add to the context of this to help us to get in the right direction? π
Is that what you had in mind?
@aliemir yes, that's essentially it! I know some of the UI libraries also extend/wrap the data-provider (like MUI's useDataGrid
) so I'm not sure how easy it would be for that change to extend into those.
Also, I'm not sure the significance but even though gql.tada draws inspiration from the TypedDocumentNode
, they actually define it as a TadaDocumentNode
In any case, some base level of support for this would be EPIC!
@kitten any chance you could provide some guidance? π I've been away from GraphQL/TypeScript for too long and struggling with this so far, but it would be awesome to see gql.tada
working in Refine!
I don't really have time to sift through and gather context here, sorry! I don't quite understand in what position your library is in, and you're welcome to ask a more specific question on our Discord, if it relates closer to how urql
or gql.tada
provide this integration.
The more important point is that gql.tada
has an integration point where it provide both, a property shaped like @graphql-typed-document-node/core
and a property shaped like graphql-js
's (i.e. TypedQueryDocumentNode
)
That's defined:
gql.tada
: https://github.com/0no-co/gql.tada/blob/db1bd6c1c2c2ace76955f6ca0f8c56d044ec0177/src/utils.ts#L24-L52@urql/core
: https://github.com/urql-graphql/urql/blob/e5c32daa34a69ff0bfd8cb74dc693826d9294a21/packages/core/src/types.ts#L17-L48I don't have enough context to know whether you're a GraphQL types "consumer" (like @urql/core
) or provider (like gql.tada
)
There's a detailed explanation on being a consumer here: https://gql-tada.0no.co/guides/typed-documents#typeddocumentnode-types
But you can also look at how urql
, villus
, or @apollo/client
do this.
Depending on how your GraphQL request API method/function is shaped you may also be interested in this helper in @urql/core
regarding optional variables: https://github.com/urql-graphql/urql/blob/e5c32daa34a69ff0bfd8cb74dc693826d9294a21/packages/core/src/types.ts#L363-L404
A small side-note, assuming again you're looking to consume these types, is to try to refrain from exposing type helpers such as ResultOf
and VariablesOf
(etc).
All GraphQL type providers will likely expose this, and if you're exposing your own this may create confusion, so typically type-consumers (i.e. GraphQL clients) will not re-expose any helpers for those and only internally define types to consume GraphQL types.
The special types I've linked are basically unions of the two referenced libraries btw βΒ meaning, they define the two different function properties that graphql-js
and @graphql-typed-document-node/core
define. The former is rarely used afaik, but it doesn't hurt to support it.
@kitten thank you for the guidance, that's more than I was hoping for!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Do intend to give this a go once I get back on our internal refine project. Stale bot is not helpful.
Yup, this is an excellent feature request. I hope to see it implemented and would love to help if any PRs open up. Absolutely not stale β€οΈ Sorry for the bot @jamesdh π
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Will be coming back around to this shortly!
Was just taking a look at what would be involved, there's a couple ways I can see doing it properly. The most aggressive would require adding GraphQL specific type parameters pretty deep through the data provider and hooks, but I think could be done in a backwards compatible way. The other way you could do it would be a wrapper hook that takes in a GraphQL query and/or mutation depending on the hook and types it that way. I personally think the second way is the ideal solution, especially because it could go even further and strongly type the fields and variables for each type of hook, for example requiring that the type of the filters for useList actually match the query you pass in.
Is your feature request related to a problem? Please describe.
Following up on @alicanerdurmaz recent excellent work in #5742, and influenced by the gql.tada's integration with other GraphQL clients, it would be very impressive if Refine were able to better leverage the TypedDocumentNode and could greatly reduce or even eliminate boilerplate/generated code.
Describe alternatives you've considered
No response
Additional context
I'm new to Refine and just becoming acquainted with how it works. Since @alicanerdurmaz added support for
meta.gqlQuery
I thought I'd give gql.tada a try. It works for validating/autocompleting the query, but as things currently exist with the GraphQL data-provider, it is unable to infer any type information from theTypedDocumentNode
Describe the thing to improve
Fully support TypedDocumentNode in addition to DocumentNode.