Resolving the "Abstract type N must be an Object type at runtime" error in GraphQL Server Union Types

Given a unique GraphQL union return type:

union GetUserProfileOrDatabaseInfo = UserProfile | DatabaseInfo

meant to be returned by a specific resolver:

type Query {
  getUserData: GetUserProfileOrDatabaseInfo!
}

I am encountering warnings and errors related to the __resolveType or __isTypeOf function:

The abstract type M must resolve to an Object type at runtime for field Query.getUserData with value { ..., __isTypeOf: [function __isTypeOf] }, received "undefined". Either the M type should provide a "resolveType" function or each possible type should provide an "isTypeOf" function.'

After extensive research on GitHub issues and Stack Overflow questions, I have yet to find a solution to fix this error.

Implementing __resolveType or __isTypeOf in my resolvers has been unsuccessful:

export const Query = {
  getUserData: (parent, args, context: IContext, info) => {
    return {
      __isTypeOf(obj) { // OR __resolveType, none of them work
        return `UserProfile`;
      },
      data: []
    };
  },
};

Answer №1

After struggling with implementing __resolveType or __isTypeOf in my resolvers, I finally found a solution by directly adding the __typename into the resolver return Object to resolve the issue.

In the implementation of the getBankAccounts resolver:

async getBankAccounts(): GetBankAccountsResponseOrUserInputRequest {
    if (shouldGetUserInputRequest()) {
      return {
        __typename: "UserInputRequest",
        ...response,
      };
    }

    return {
      __typename: "GetAccountsResponse",
      accounts,
    };
  }

I hope this solution can be useful for someone facing a similar challenge.

Answer №2

Your resolver map is not configured correctly.

When passing the resolver map to ApolloServer (or makeExecutableSchema), it should be an object with keys representing type names in your schema. Each key should map to another object with field names on that type, each mapping to a resolver function.

const resolvers = {
  SomeType: {
    someField: (parent, args, context, info) => { ... },
  },
}

The same resolver map is used for providing the resolveType function for unions or interfaces. The structure remains similar, but the key becomes __resolveType and corresponds to the union or interface's name:

const resolvers = {
  SomeType: {
    someField: (parent, args, context, info) => { ... },
  },
  SomeUnion: {
    __resolveType: (parent) => { ... },
  }
}

The resolveType function must return a string matching an existing object type in your schema.

If you opt for __isTypeOf over __resolveType, note that isTypeOf is specific to an object type and not the interface or union itself. Refer to the docs for clarity. In this case, the resolver map looks like:

const resolvers = {
  SomeType: {
    someField: (parent, args, context, info) => { ... },
    __isTypeOf: (parent) => { ... },
  },
}

__isTypeOf should always return either true or false, confirming if the passed object matches the type.

Choose between __resolveType or __isTypeOf; using the latter requires adding it to every possible object type in the union or interface.

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

Unable to utilize Google Storage within a TypeScript environment

I'm encountering an issue while attempting to integrate the Google Storage node.js module into my Firebase Cloud functions using TypeScript. //myfile.ts import { Storage } from '@google-cloud/storage'; const storageInstance = new Storage({ ...

Issue encountered while deploying Next.js application on vercel using the replaceAll function

Encountering an error during deployment of a next.js app to Vercel, although local builds are functioning normally. The issue seems to be related to the [replaceAll][1] function The error message received is as follows: Error occurred prerendering page &q ...

Using TypeScript 4.1, React, and Material-UI, the className attribute does not support the CSSProperties type

Just starting out with Material-UI and we're utilizing the withStyles feature to style our components. Following the guidelines laid out here, I successfully created a classes object with the appropriate types. const classes = createStyles({ main ...

React: The Material-UI autocomplete input, controlled with the React Hook Form `<controller>` component, experiences issues when the `multiple` prop is set to `true`

Currently facing challenges with managing an autocomplete MUI component using the <controller> component in react-hook-form. Take a look at the code snippet below: <Controller control={control} name="rooms" render={({ field }) =&g ...

What is the best way to trim a string property of an object within an array?

I am seeking a solution to access the "description" property of objects within an array and utilize a string cutting method, such as slice, in order to return an array of modified objects. I have attempted using for loops but have been unsuccessful. Here ...

Creating objects based on interfaces in TypeScript is a common practice. This process involves defining

Within my TypeScript code, I have the following interface: export interface Defined { 4475355962119: number[]; 4475355962674: number[]; } I am trying to create objects based on this interface Defined: let defined = new Defined(); defined['447 ...

Tips for modifying the JSON format within a Spring and Angular project

I am utilizing Spring for the backend and Angular for the frontend. Below is my REST code: @GetMapping(path = "/endpoint") public @ResponseBody Iterable<Relations> getGraphGivenEndpointId(@RequestParam(value = "id") int id) { return ...

Is it possible to verify if the @Output is correctly wired up within an Angular component?

When working with Angular and TypeScript, it is possible to access the bound @Input values in the ngOnInit method of a component. However, there isn't a straightforward way to check if a particular @Output event binding has been set up on the componen ...

Utilize the identical element

Incorporating the JwPaginationComponent into both my auction.component and auctiongroup.component has become a necessity. To achieve this, I have created a shared.module.ts: import { NgModule } from '@angular/core'; import { JwPaginationCompon ...

Different ways to reference a variable in Typescript without relying on the keyword "this" throughout the codebase

Can we eliminate the need to write "this" repeatedly, and find a way to write heroes, myHero, lastone without using "this"? Similar to how it is done in common JavaScript. https://i.stack.imgur.com/TZ4sM.png ...

Improving my solution with PrimeNG in Angular2 - fixing the undefined tag error

After working with Angular for just three days, I successfully set up a login page dashboard using a web API solution. Everything was working great until I encountered an issue when trying to load the PrimeNG DataTableModule into my components. After searc ...

Error encountered while compiling an Asp.Net Core project due to exceeding the maximum allowable path length in the

Encountering a critical error during the build process with Visual Studio 2016 update 3 Asp.Net Core. The build is interrupted with the following message: Severity Code Description Project File Line Suppression State Error MSB4018 The "FindC ...

Who is the intended audience for the "engines" field in an npm package - consumers or developers?

As the creator of an npm library, I have included the current LTS versions of Node.js and npm in the package manifest under the engines field. This ensures that all contributors use the same versions I utilized for development: Node.js <a href="/cdn-cgi ...

Implementing pagination within an Angular 11 Mat-table with grouping feature

Encountering an interesting issue with MatTable pagination and grouping simultaneously. I have two components each with a Mat-table featuring Pagination+Grouping. ComponentOne functions smoothly without any issues. When choosing to display 5 elements pe ...

What is the process for including a new item in the p-breadcrumb list?

Having trouble getting my code to add a new item to the p-breadcrumb list on click. Any assistance would be greatly appreciated. Thank you in advance! Check out the live demo here ngOnInit() { this.items = [ {label: 'Computer'}, ...

The Context API's `useContext` hook appears to be malfunctioning, persistently

My situation is as follows: export const LocationContext = createContext(null); export const LocationProvider = LocationContext.Provider; export const useLocationContext = () => useContext(LocationContext); Using the Provider: export const Search = () ...

Make sure to include a property that is indexed when typing

I am currently working on defining a type to represent a list (hash) of HTTP headers. This type is supposed to be a hash that only contains key / string pairs: type TStringStringHash = { [key: string]: string } However, the issue I am facing is that i ...

Tips for accurately typing a "Type Mapping" function

In my code, I have a specific type designed for a function that takes one type I as input and returns another type O as output. Here is how it currently looks: export interface IFunctionalMapping<I, O, K extends keyof O> { [prop: Extract<O[K], ...

Checking the formik field with an array of objects through Yup for validation

Here is a snippet of the code I'm working on: https://codesandbox.io/s/busy-bose-4qhoh?file=/src/App.tsx I am currently in the process of creating a form that will accept an array of objects called Criterion, which are of a specific type: export inte ...

Troubleshooting common issues while setting up React Native with TypeScript

After carefully following the steps outlined in this guide on configuring a React Native project using TypeScript: https://facebook.github.io/react-native/blog/2018/05/07/using-typescript-with-react-native, I encountered a total of fifteen errors from the ...