Unable to use generic arguments on withFilter in Subscriptions
DevelopmentByDavid opened this issue · comments
TLDR
Typing issue when using generics on the withFilter
function supplied by the mercurius
package on subscriptions.
Problem
Given the following code
type PayloadType = { eventId: string };
export const resolvers = {
Subscription: {
likeCountChanged: {
subscribe: withFilter<PayloadType>(
(parent, args, ctx) => ctx.pubsub.subscribe('likeCountChanged'),
(payload, args, ctx) => Question.doesEventMatch(args.eventId, payload)
),
},
},
}
I get the following error
Type '{ subscribe: (root: any, args: Record<string, any>, context: MercuriusContext, info: GraphQLResolveInfo & { mergeInfo?: MergeInfo | undefined; }) => AsyncGenerator<...>; }' is not assignable to type 'SubscriptionResolver<Maybe<ResolverTypeWrapper<EventQuestion>>, "likeCountChanged", {}, MercuriusContext, RequireFields<SubscriptionlikeCountChangedArgs, "eventId">> | undefined'.
Property 'resolve' is missing in type '{ subscribe: (root: any, args: Record<string, any>, context: MercuriusContext, info: GraphQLResolveInfo & { mergeInfo?: MergeInfo | undefined; }) => AsyncGenerator<...>; }' but required in type 'SubscriptionResolverObject<Maybe<ResolverTypeWrapper<EventQuestion>>, {}, MercuriusContext, RequireFields<SubscriptionlikeCountChangedArgs, "eventId">>'.ts(2322)
graphql-types.ts(439, 5): 'resolve' is declared here.
My relevant generated code looks the same as shown in the examples folder here:
mercurius-typescript/examples/codegen-gql-files/src/graphql/generated.ts
Lines 102 to 148 in a0eaf6a
Solutions
- Adding a resolve field that returns null
type PayloadType = { eventId: string };
export const resolvers = {
Subscription: {
likeCountChanged: {
subscribe: withFilter<PayloadType>(
(parent, args, ctx) => ctx.pubsub.subscribe('likeCountChanged'),
(payload, args, ctx) => Question.doesEventMatch(args.eventId, payload)
),
resolve: () => null
},
},
}
- Not using the generic also gives no errors
// no errors with the below code if I remove the generic argument
export const resolvers = {
Subscription: {
likeCountChanged: {
subscribe: withFilter(
(parent, args, ctx) => ctx.pubsub.subscribe('likeCountChanged'),
(payload, args, ctx) => Question.doesEventMatch(args.eventId, payload)
),
},
},
}
Also, I'm not sure if I should be asking this question here, in the graphql-codegen package, or in mecurius repo, but since this possibly has to do with the generated code then I thought I'd ask here first.
From my understanding, I should not need to use the resolve field. If I need to, then I must have missed something in https://github.com/mercurius-js/mercurius/blob/master/docs/subscriptions.md#subscription-filters
@DevelopmentByDavid I just took a look at this issue and it seems like this issue appears when the generic you specify doesn't match the generated type, that's how I could reproduce it, but that's not an issue with this package of course, could you confirm if making sure the types match solves this issue? remember that the type is not the field, but an object with the field with it's correct name, for example, withFilter<{ likeCountChanged: number }>
and not withFilter<number>
@PabloSzx You are correct! Thank you! I did not realize that there needed to be a nested field with the same name as the subscription itself.
Where is the above requirement documented? Is this something to do with graphql.js itself? If this is mercurius specific I'd be happy to open a PR to add the documentation necessary to the subscriptions section.
@PabloSzx You are correct! Thank you! I did not realize that there needed to be a nested field with the same name as the subscription itself.
Where is the above requirement documented? Is this something to do with graphql.js itself? If this is mercurius specific I'd be happy to open a PR to add the documentation necessary to the subscriptions section.
This is from the graphql.js implementation, and if you think about it, it makes sense, since it possible that from a single pubsub publish to trigger multiple different subscriptions
I see. I'm still a bit new to graphql and learning. Thank you for letting me know and being so responsive! Apologies for the extra work this may have caused you.