Create the accurate data format rather than a combination in GraphQL code generation

In the process of migrating a setup that mirrors all the types exactly as on the server to one based solely on the document nodes we've written.

Currently, the configuration is in .graphqlrc.js

/** @type {import('graphql-config').IGraphQLConfig} */
const graphqlConfig = {
  schema: process.env.NEXT_PUBLIC_API_URL,
  documents: './src/graphql/**/*.ts',
  extensions: {
    codegen: {
      hooks: {
        afterAllFileWrite: ['prettier --write'],
      },
      generates: {
        './src/__generated__/graphql.ts': {
          plugins: [
            'typescript',
            'typescript-operations',
            {
              add: {
                content: '/* eslint-disable */',
              },
            },
          ],
          config: {
            disableDescriptions: true,
          },
        },
        './src/__generated__/introspection-result.ts': {
          plugins: ['fragment-matcher'],
          config: {
            useExplicitTyping: true,
          },
        },
      },
    },
  },
}

This setup currently produces output like below:

export type QueryName = {
  __typename?: 'Query'
  resource?:
    | { __typename?: 'A' }
    | { __typename?: 'B' }
    | {
        __typename?: 'C'
        id: string
        prop1: any
        prop2: any
      }
}

However, I was expecting something more specific like:

export type QueryName = {
  __typename?: 'Query'
  resource?: {
        __typename?: 'C'
        id: string
        prop1: any
        prop2: any
  }
}

Since I am only querying for type C, the current generated types will impact a lot of code. If we could generate what I expect, it would simplify the changes needed.

I've experimented with the configuration mentioned here but haven't found a solution yet. Please advise if this is possible or suggest any resources to help solve this issue.

Thank you in advance!

Answer №1

After exploring different options, I settled on utilizing the tiny-invariant library for this particular task. Below is an example of how it can be implemented:

const {data} = useUserQuery({variables: {id}});

// additional code...

invariant(data.user.__typename === "User");

// at this point, we should have the desired type

Answer №2

Here's a fantastic solution!

Imagine you have this scenario:

export type FetchProductQuery = {
  __typename?: 'Query'
  product?:
    | { __typename: 'Missing'; message: string }
    | {
        __typename: 'Item'
        id: string
        name: string
        price: number
      }
    | null
}

In this case, you can utilize the Extract utility type

type QueryItemData = Extract<FetchProductQuery['product'], { __typename: 'Item' }>
type QueryMissingData = Extract<FetchProductQuery['product'], { __typename: 'Missing' }>

With these types, you'll be able to create any future types.

Answer №3

An alternative approach can be:

if (data.user.__typename === "User") { ... };

This will guarantee that it is referencing the specific type in the union as required

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 React namespace is missing the exported member 'InputHTMLAttributes', and the MenuItemProps interface is incorrectly extending the ListItemProps interface

I am currently working with Material-UI and typescript. I have installed the typescript types using npm install -D @types/material-ui. After loading my webpage, I encountered the following errors: ERROR in [at-loader] ./node_modules/@types/material ...

Tips for adjusting the language settings on a date picker

Is there a way to change the language from English to French when selecting a month? I believe I need to configure something in the core.module.ts. How can I achieve this? https://i.sstatic.net/Cpl08.png @NgModule({ declarations: [], imports: [ Co ...

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 ...

Encountering a problem while bringing in screens: 'The file screens/xxx cannot be located within the project or any of these folders.'

I am currently working on an iOS application using React Native technology. During the process of importing a specific screen, I encountered an error message. Can anyone provide guidance on how to resolve this issue? Error: Unable to resolve module scree ...

Substitute all instances of null bytes

I need to remove null bytes from a string. However, after replacing the null bytes \u0000 in the string let data = {"tet":HelloWorld.\u0000\u0000\u0000\u0000"} let test = JSON.parse(data).tet.replace("\u0000", ""); I always ...

Utilize prop-types inheritance when a component is rendered via props

Is it possible to inherit prop-types when a component is rendered via the parents prop, without direct access to 'ChildProps' and 'Props' interface? Parent Component interface ChildProps { counter: number; setCounter: React.Dispat ...

Set up SystemJS to properly load my Angular 2 component module

Recently, I made the switch from ng1 to ng2. I successfully imported Angular 2 and its modules into my project: <script src="/node_modules/systemjs/dist/system.src.js"></script> <script src="/node_modules/rxjs/bundles/Rx.js"></script& ...

Extremely sluggish change identification in combination Angular application

We are encountering consistent issues with slow change detection in our hybrid AngularJS / Angular 8 app, especially when dealing with components from different versions of the framework. The problem seems to arise when using older AngularJS components wit ...

Passing data between parent and child components within an Angular application using mat tab navigation

I am currently working on a project, which can be found at this link. Current Progress: I have implemented a mat tab group with tabs inside the app-component. When a tab is clicked, a specific component is loaded. Initially, most of the data is loaded in ...

Default functionality of Typescript paths imports fails to operate properly

Can anyone help me figure out how to set up default imports in my .ts files using the paths specified in my tsconfig.base.json? I have this file defined as default in the File Type > Typescript Config. https://i.sstatic.net/LvBGV.png The import statem ...

Navigation arrows for sliding`

Is there a way to add custom right/left arrows to the Ionic slider component? Demo: Check it out on Stackblitz Note: Make sure to refer to the home.html page for more details. https://i.sstatic.net/jQ62l.png .html <ion-slides [pager]="true" [slide ...

Unused code splitting chunk in React production build would improve performance and efficiency of

When running the command npm run build, a build directory is generated with js chunks. I have observed an unfamiliar file named [number].[hash].chunk.js that does not appear in the list of entrypoints in the asset-manifest.json file. Instead, this mysteri ...

Insert dynamic values into div attributes

I am looking for a way to dynamically add div attributes in Angular 7. Here is what I attempted: <div *ngFor="let e of etats._embedded.etats" style="background: {{e.codeCouleur}} !important;" data-code="{{e.id}}" data-bg={{e.codeCouleur}}>{{e.no ...

Tips on integrating a `resolveType` in GraphQL

Having difficulty querying a specific MongoDB document (trivia) using GraphQL due to an issue with the trivia.rounds field, which is expected to return an array of objects (LightningRound or MultipleChoiceRound). schema.graphql type Trivia { _id: Strin ...

Angular 2 and SystemJS: Dealing with the Challenge of Circular Dependencies

I have been struggling with a problem that seems to stem from a circular dependency. Despite conducting thorough research, I have not been able to find a suitable solution. It appears to be similar to the issue discussed here: TypeError: b is undefined in ...

You are unable to call upon an object that may be of type 'undefined' in typescript

Among all the other inquiries on this topic, my issue lies with the typescript compiler seeming perplexed due to the following code snippet: if(typeof this[method] === "function"){ await this[method](req,res,next) } The error message I am en ...

How can I incorporate multiple quality sources into a flowplayer using Angular?

Is there a way to add multiple sources with different qualities like 1080p, 720p etc.? Thank you in advance. flowplayer('#my_player', { src: '../assets/videos/video_1080p.mp4', // title: 'This is just demo&apo ...

Merging declarations fails to function properly following the release of the npm module

The file core.ts contains the definition of a class called AnyId. In another file named time.ts, more methods are added to the AnyId class. This is achieved by extending the type of AnyId using declaration merging: declare module './core' { in ...

Facing an issue with the TypeScript error in the Tailwind-Styled-Component Npm package. Any suggestions on how to troub

module.styles.ts File import tw from "tailwind-styled-components"; export const Wrapper = tw.div` bg-green-500 `; export const Link = tw.a` text-blue-500 `; home.jsx File import React from "react"; import { Wrapper, Link } from &qu ...

Adjust website content depending on user's authentication status

My goal is to display a logout button when the user is logged in and a login button if they are not. I am using JSON tokens to determine if a user is logged in or not, by checking if the token is null. However, this approach does not seem to be working. Ca ...