Struggling to understand how to implement Schema Directives after transitioning to Typescript

After spending several days rewriting my GraphQL server to Typescript, I found myself struggling with defining Schema Directives. Despite extensive googling, I could not find any examples of using "more advanced" Apollo GraphQL with Typescript.

Everything was working perfectly for me when using plain Javascript. Here is an example of how my Directive looks:

// 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 utilize makeExecutableSchema from the graphql-tools library, which is set up 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."
  },
})

Due to the constructor of SchemaDirectiveVisitor being protected, I am unable to instantiate the class from there. I am relatively new to Typescript and may be misunderstanding something or missing basic concepts, so any tips or suggestions would be greatly appreciated as I am currently stuck on this issue.

Thank you :-)

Answer №1

It is crucial to verify that you are importing SchemaDirectiveVisitor from the correct package - specifically graphql-tools instead of apollo-server. Due to potential version discrepancies, it is highly probable that the SchemaDirectiveVisitor classes provided by these packages may not be interoperable.

Answer №2

In your visitFieldDefinition method, there are two arguments being used.

The way this class is implemented can vary depending on how graphql is implemented.

If you are using apollo-server:

When working with SchemaDirectiveVisitor, you must override one of the visit methods, each of which only takes a single argument. This means that the method is overloaded, not overridden.

For more information, please see:

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

If you are using graphql-tools:

This method requires 2 arguments in the form of

visitFieldDefinition(field: GraphQLField<any, any>, details: { objectType: GraphQLObjectType | GraphQLInterfaceType })

For more information, please see:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The Ultimate Guide to Sorting Multi-dimensional Javascript Arrays with Complex Numerical Values

I need to organize this array: const array = [ [18, [18, 16], 16], 15, [18, 19, 51], [[18, 16], 15, [14, 13]], [10, 9, 20], 99, 49, [11, [22, 10], [[10, 9], 11, 9, [1, 2]], 100, 72], [[11], [[19, 14], [77, 18]]] ]; Arrange this array in ...

Determine the consistent type for numerous properties

Is it feasible to have Typescript automatically infer the type of multiple properties to be the same, or even infer the types based on a specific property? For example, consider the following code snippet -> interface Test<T> { value1: T; val ...

Performing multiple lookups on the same MongoDB collection

In my child collection, there are 3 fields linked to the same master collection. When merging them into the root element, the third one overwrites the first two, which is expected since all three lookups refer to the same collection. However, I want to avo ...

Clicking on text triggers image display

My journey in coding is just starting and I have a good understanding of the basics of HTML, CSS, Javascript, and jQuery. I am trying to make an image appear when I click on text but struggling with the implementation. I'm working on a restaurant web ...

Is there a way to make a TypeScript function accessible in intellisense from a JavaScript file?

I recently started learning TypeScript and I must say, I am really enjoying it. However, I have encountered a small issue. When I try to type in a JavaScript file, such as a function from my TypeScript file, it doesn't show up in intellisense. Does an ...

Enhancing user registration with Bootstrap 4 validation, ensuring password confirmation and disabling submit button until form is successfully validated

There are 3 input fields in a simple form, each with its own regex pattern. The 'Password' and 'Confirm Password' fields must match. If they don't, a message "Not Matching" is displayed. If they do, "Valid" is displayed. I am tr ...

A basic structure for a JSON array

Perhaps my next question may appear silly, but I'll ask it anyway :) Here is the structure in question: { "name": "Erjet Malaj", "first_name": "Erjet", "work": [ { "employer": { "id": "110108059015688 ...

Iterate over the array and show the elements only when a click event occurs

I am trying to create a loop through an array (array) and display the elements one by one only after clicking a button (bt). However, when I run this code, it only shows the last element of the array (i.e. honda). Can someone please help me fix this issu ...

Utilize Launchdarkly in React by incorporating it through a custom function instead of enclosing it within

Currently, I am adhering to the guidelines outlined by launchdarkly. Following the documentation, I utilized the following code snippet: import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk'; (async () => { const LDProvider = a ...

Showing an image based on the selected value from a dropdown menu using jQuery

I am trying to dynamically display the correct image based on the option selected in a dropdown menu. Currently, I am able to show the image if the option value matches the filename; however, I need help with displaying the image using echo rather than t ...

Vue displaying element tags without proper color rendering

Currently, I am using Vue3 in VS Code and encountering an issue where the colors of the Vue tags appear as white, making it difficult for me to differentiate between the template, script, and style tags. If you would like to take a look at the code sample ...

If the condition is true, apply a class with ng-class when ng-click is triggered

I am facing a situation similar to toggling where I am adding the class col-xs-6 to divide the page into two views. Initially, when I click, I set a variable value as true and in ng-class, I check for a condition to append the col-xs-6 class. Below is the ...

Firebase is not updating the number

Having just started with Firebase, I have been following all the guidelines for web Firebase auth. I have successfully managed to login, log out, and update all data except for the phone number. Despite receiving a success message in the console, my phone ...

Retrieving information from an openDatabase using AngularJS

Encountering an issue while trying to retrieve data from openDatabase and display it in a listview. Following advice from a thread, I added $scope.$apply(); after $scope.items = $data;, but this resulted in an error: [$rootScope:inprog] $apply already in p ...

"By selecting the image, you can initiate the submission of the form

I am trying to figure out why clicking on the image in my form is triggering the form submission by default. Can someone please provide guidance on this issue? <form name="test1" action="er" method="post" onsubmit="return validateForm()" <input ty ...

The React error message refuses to disappear even after attempting to refresh the page

Currently, I am immersed in a React project where I have encountered an issue on the Register Page. All errors are being added to a Message component. Interestingly, even after encountering a React error (such as 'Cannot read properties of undefined&a ...

Tips for creating a personalized callback within a user function using JavaScript

Utilizing callbacks is a common practice when working with third-party libraries like jQuery. However, I have encountered a situation where I need to implement my own callback function. Consider the following snippet from my current code: // Get All Rates ...

The input value "HH:MM" does not match the expected format of 'FormatOptions' for this parameter

I created a function that takes in two parameters: data and format. I am attempting to define an ENUM(FormatOptions) for the "format" parameter. However, I encountered the following error: Argument of type '"HH:MM"' is not compatible with param ...

The script for the history API's statechange function is causing duplication of function calls with every change event

After implementing the jquery history plugin in a demo that loads a section of a specific page each time a nav item is clicked, I noticed that the History.Adapter.bind(window, 'statechange', function() code gets duplicated every time a new link i ...

The csurf token in Node.js consistently shows as invalid

Upon installing the csurf package on my Node.js Express application, I encountered an issue with validating the CSRF token. Despite properly displaying the token in the form as name="_csrf" with a hash value set using req.csrfToken(), I consistently receiv ...