Tominek
Tominek

Reputation: 158

Can't figure out how to use Schema Directives when moving to Typescript

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 :-)

Upvotes: 3

Views: 2378

Answers (2)

Daniel Rearden
Daniel Rearden

Reputation: 84657

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.

Upvotes: 2

MegaMind
MegaMind

Reputation: 671

I see two arguments in your visitFieldDefinition method.

The implementation of this class varies with implementation of the graphql.

If you are using apollo-server:

When implementing SchemaDirectiveVisitor you need to override one of the visit method, and these methods take only one argument. Hence, the method is overloaded and not overridden.

Please refer to the page below :

https://www.apollographql.com/docs/apollo-server/schema/creating-directives/

If you are using graphql-tools:

The method takes 2 arguments which look like visitFieldDefinition(field: GraphQLField<any, any>, details: { objectType: GraphQLObjectType | GraphQLInterfaceType })

Please refer to the page below :

https://www.graphql-tools.com/docs/legacy-schema-directives/#implementing-schema-directives

Upvotes: 1

Related Questions