type-graphql
type-graphql copied to clipboard
can't override parent method
Describe the Bug According to the docs it should be possible to override parent methods in child resolvers. This seems not to work due to typing errors.
Let's say I override a generated crud resolver like this:
@Resolver()
class CustomUserResolver extends UserCrudResolver {
// overriding UserCrudResolver.createUser to publish events:
@Mutation({ name: 'createUser' })
async createUser(
@Ctx() ctx: any,
@Info() info: GraphQLResolveInfo,
@Args() args: UserCreateInput,
@PubSub('USERS') publish: Publisher<UserCreateInput>,
): Promise<User> {
// let parent handle original intent
const ret = await UserCrudResolver.prototype.createUser.call(this, ctx, info, args)
// then publish as successful
await publish({ email: args.email })
// and return original
return ret
}
@Subscription({
topics: 'USERS',
})
newUser(@Root() { email }: UserNotification): UserNotification {
info('New user onboard: ' + email)
return { email }
}
}
This will err:
Property 'createUser' in type 'CustomUserResolver' is not assignable to the same property in base type 'UserCrudResolver'.
Type '(ctx: any, info: GraphQLResolveInfo, args: UserCreateInput, publish: Publisher<UserCreateInput>) => Promise<User>'
This also shows my intent: to add publication events to existing functions. I also have an issue with doing that through inheritance, and instead favor AOP approach for that. (See https://github.com/MichalLytek/type-graphql/discussions/1294)
Environment (please complete the following information):
- OS: MacOS
- Node 16.4.2
- Package 1.1.1
- TypeScript version 4.6.4
I no longer see the need to intercept to achieve my goals, because your example shows how to tap into prisma subscriptions like this:
type UserNotification = {
email: string
}
@Resolver()
class SubscriptionsResolver {
@Subscription({
subscribe: (root, args, context, info) => context.prisma.$subscribe.users({ mutation_in: [args.mutationType] }),
})
newUser(@Root() { email }: UserNotification): User {
info('New user onboard: ' + email)
return { email }
}
}
But then I get an error which I don't see the cause of (as all the types are there afaik):
NoExplicitTypeError: Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for 'newUser' of 'SubscriptionsResolver' class.
type UserNotification
You need to make it a class with decorators.
But in your example you also just provide the NotificationPayload
as class, and the Notification
as interface. In my example above I do the same. User
is a class exported by your crud mechanism, while UserNotification
is the interface.