I spent few days rewriting my GraphQL server to Typescript, but in the end, got stuck with defining Schema Directives. Already spent a lot of time googling and found no examples of "more advanced" Apollo GraphQL with Typescript.
It works perfectly for me when using plain Javascript, had no issues with that and my Directive looks like this:
// TS but no difference from JS in terms of extended class or method overriden
export default class UserAuthDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field: any, details: any) {
field._requiredRole = this.args.role
const { resolve = defaultFieldResolver } = field
field.resolve = function (...args: any) {
// LOGIC CHECKING ROLES
}
}
}
I use makeExecutableSchema from graphql-tools library which looks like this:
// Again basically identical with original JS
const schema = makeExecutableSchema({
typeDefs: mergeTypes(types, { all: true }),
resolvers: loadResolvers(),
logger: {
log: (e) => logger.error(e.message, e),
},
allowUndefinedInResolve: false,
inheritResolversFromInterfaces: true,
resolverValidationOptions: {
allowResolversNotInSchema: false,
requireResolversForResolveType: true,
},
schemaDirectives: {
userHas: UserAuthDirective,
// ^^^ Here I'm getting. "Type 'typeof UserAuthDirective' is not assignable to type 'typeof SchemaDirectiveVisitor'. Types of property 'visitSchemaDirectives' are incompatible."
},
})
The constructor of SchemaDirectiveVisitor is protected therefore I can't instantiate the class from there. I am not really advanced Typescript user, so maybe I am just understanding it completely wrong or missing some basic concepts, but I got really stuck on this and will be glad for any tips or guesses what I could be doing wrong.
Thanks :-)
You need to make sure you're importing SchemaDirectiveVisitor
from the right package -- graphql-tools
and not apollo-server
. Depending on the versions of each package, it's very likely that the SchemaDirectiveVisitor
classes exported by each the packages are not compatible with one another.