How can you keep TypeScript satisfied when extending classes that come from 'node modules'?

Update: Included ARTICLES_QUERY, tsconfig.json, and package.json as requested.

Update 2: The current solution is functional, but it doesn't seem ideal. Any suggestions for improvement would be appreciated.

export default class InterfaceGraphQLApi extends GraphQLDataSource {
  baseURL = "http://localhost:4545/admin/api";

  query = super.query;

Update 3: @Max's solution resolves the issue with the query field, but it causes TypeScript to fail compiling due to another 'error': https://i.sstatic.net/xOK8p.png

ARTICLE_QUERY snippet below:

const ARTICLE_QUERY = gql`
  query Article($id: ID!) {
    Article(where: { id: $id }) {
      title
      text
      video {
        youtube {
          ... on OEmbedVideo {
            html
            type
          }
        }
      }
      podcast {
        spotify {
          ... on OEmbedRich {
            html
            type
          }
        }
      }
      images {
        file {
          filename
        }
      }
    }
  }
`;

Update 4: The modified version of Max's solution is functioning correctly.


I'm fairly new to TypeScript. I'm using an npm library to set up a GraphQL data source for my Apollo Server project. I'm extending the class provided by this library in my project.

 import { GraphQLDataSource } from "apollo-datasource-graphql";
import { gql } from "apollo-server";

const ARTICLES_QUERY = gql`
  query {
    allArticles {
      title
      text
      id
      status
      images {
        file {
          filename
        }
      }
    }
  }
`;

export default class InterfaceGraphQLApi extends GraphQLDataSource {
      baseURL = "http://localhost:4545/admin/api";

      async getArticles() {
        try {
          const response = await this.query(ARTICLES_QUERY);

However, TypeScript is giving an error for this.query, stating

https://i.sstatic.net/WEWEg.png

The query method is inherited from the imported library's class. How can I resolve this to make TypeScript happy?

Here is tsconfig.json:

{
  "compilerOptions": {
    "target": "ESNext",
    "lib": [
      "esnext",
      "dom"
    ],
    "skipLibCheck": true,
    "outDir": "dist",
    "strict": false,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "sourceMap": true
  },
  "exclude": [
    "node_modules"
  ]
}

And here is package.json:

{
  "dependencies": {
    "apollo-datasource-graphql": "^1.3.2",
    "apollo-server": "^2.10.1",
    "graphql": "^14.6.0"
  },
  "devDependencies": {
    "babel-eslint": "^10.0.3",
    "eslint": "^6.8.0",
    "eslint-config-airbnb-base": "^14.0.0",
    "eslint-config-prettier": "^6.10.0",
    "eslint-plugin-prettier": "^3.1.2",
    "pino": "^5.16.0",
    "prettier": "^1.19.1",
    "ramda": "^0.26.1",
    "typescript": "^3.8.3"
  },
  "scripts": {
    "dev": "tsc && node dist/index.js"
  }
}

Additionally, I am seeking guidance on the necessary type definitions for Apollo Server and GraphQL -- When searching for 'Apollo Server type definitions,' I found this resource, which has several dependencies that need to be downloaded individually. Is there something like @types/apollo-server? (When running yarn @types/apollo-server, I received

https://registry.yarnpkg.com/@types%2fapollo-server: Not found.
)

Any assistance would be greatly appreciated!

Answer №1

Hey there! Just wanted to let you know about an open PR in the apollo-datasource-graphql repository that you might find interesting: Check it out here!

If you're looking for a temporary solution, try changing your import statement from:

import { GraphQLDataSource } from 'apollo-datasource-graphql';

to

import { GraphQLDataSource } from 'apollo-datasource-graphql/src';

Also, I stumbled upon something intriguing while doing some research. I discovered a section in the documentation on Apollo Server where they discuss defining an API as a resource rather than just a GraphQL server - which seems relevant to your code.

Furthermore, if you encounter any other issues causing tsc compilation errors, navigate to the apollo-datasource-graphql folder within your node_modules and locate the query function. Make sure to provide the query parameter in the options object as shown below:

const response = await this.query(ARTICLE_QUERY, { query: ARTICLE_QUERY,  variables: { id }});

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

Transforming httpClient responses into structured model objects in Angular 6

I am seeking guidance on the usage of Angular 5 httpClient. This particular model class contains a method called foo() that I wish to retrieve from the server export class MyClass implements Deserializable{ id: number; title: string; deserialize(i ...

Implementing click event binding with various CSS styles in Angular

Is there a way to attach multiple css classes to the click event of the Submit button in Angular? I want the style to change when the button is clicked. HTML <div class="mainbody" [ngClass]="getStyle"> <button (click)=&quo ...

Is it possible to eliminate the arrows from an input type while restricting the change to a specific component?

Is there a way to remove the arrows from my input field while still applying it only to the text fields within this component? <v-text-field class="inputPrice" type="number" v-model="$data._value" @change="send ...

Creating a button that displays the current day with Angular

I'm in the process of developing a timetable app that features buttons for the previous day, current day, and next day. How can I implement a button to specifically show the current day? HTML File <button type="button" (click)="previousDay()" ...

Creating custom typings in a typings.d.ts file does not address the issue of importing a JavaScript library

I'm attempting to integrate the Parse-server JS sdk into an angular 8 application, but no matter what approach I take, I encounter errors. Here is what I have tried: Creating custom typings.d.ts files with declare var parse: any; Installing the @ty ...

Angular 7/8 - A guide to accessing URL parameters within the app component

Currently, I have implemented Single Sign-On feature on my application. However, for testing purposes, I need to extract values from the URL localhost:4200/?id=test&name=testing&<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfe ...

Exploring Angular2: The Router Event NavigationCancel occurring prior to the resolution of the Route Guard

My application has routes protected by an AuthGuard that implements CanActivate. This guard first checks if the user is logged in and then verifies if certain configuration variables are set before allowing access to the route. If the user is authenticated ...

Tips for implementing server-side pagination using NestJS

Working with a MEVN stack that includes Nestjs, MongoDB (mongoose), I am currently tackling the task of setting up server-side pagination. I've decided to utilize mongoose-aggregate-paginate-v2 for this purpose, but so far, I haven't been able to ...

Simplify a function by lowering its cyclomatic complexity

This particular function is designed to determine whether a specific cell on a scrabble board qualifies as a double letter bonus spot. With a cyclomatic complexity of 23, it exceeds the recommended threshold of 20. Despite this, I am unsure of an alterna ...

Accessing lifecycle methods for React components in TypeScript as a member

Utilizing the typescript react starter for tsx-driven react implementations requires specifying member access (public, private, protected) for any method utilized within a class component. This requirement stems from, I believe, the tslint.json file. Can ...

How can you dynamically disable a radio option button using Angular rendering without relying on an ID?

Is there a way to disable the male radio button without using an id, and utilizing angular rendering2? It seems like it's not working for me. I need to make this change only in the form.ts file, without altering the HTML code. form.html <label& ...

The definition of "regeneratorRuntime" is missing in the rete.js library

After encountering a problem, I managed to find a potential solution. My current challenge involves trying to implement Rete.js in Next.js while using Typescript. The specific error message that's appearing is: regeneratorRuntime is not defined Be ...

Show just a single error message if there are two validation errors present

In my AngularJS timepicker, users can choose multiple time segments for each day. The code has validation to detect duplicates and overlapping time segments. For example, entering 11:00am - 12:00am twice will trigger two error messages: 'Overlapping t ...

The string is being added to an array twice

I am managing two sets of lists where strings will be transferred between them. One set contains a list of strings for searching purposes. The other set contains the same list of strings but is not used as a filter. The second set functions in a similar ...

Learn how to define an object with string keys and MUI SX prop types as values when typing in programming

I want to create a comprehensive collection of all MUI(v5) sx properties outside of the component. Here is an example: const styles = { // The way to declare this variable? sectionOne: { // What type should be assigned here for SXProps<Theme>? } ...

Transforming an Observable of an Array into an Observable of individual items

Trying to convert an Observable<Array<ISource>> to an Observable<ISource>. To accomplish this: this.sources$ = this.store$ .select(fromRoot.getSourceEntities) .map(sourceEntities => { return sourceEntities .filt ...

To retrieve JSON objects depending on today's date

My data is stored in a JSON file named tasks. The structure of this template can be visualized as follows: https://i.sstatic.net/MCSit.png Data Structure of JSON File [ { "taskName": "Task - 1", "id": "01", "startDate": "2019-04-17T18:30:0 ...

Attaching a function to a designated slot attribute

Currently, I am utilizing VUE 2.6.11 along with class components. My current objective involves encapsulating components that can serve as modals inside a separate component responsible for managing the modal state. According to the documentation, it is p ...

The use of the .reset() function in typescript to clear form data may lead to unexpected

I've been trying to use document.getelementbyID().reset(); to reset form values, but I keep running into an error in TypeScript. Property 'reset' does not exist on type 'HTMLElement'. Here's how I implemented it: const resetB ...

Obtaining a Comprehensive Response (not limited to just the body) through Angular 4 HTTP Requests

I am currently working on getting a full response from my HTTP calls. Following the guidelines in the Angular documentation, I have set my HTTP call options as {observe: 'response'} However, when I implement this, I encounter the following error ...