graphql-code-generator icon indicating copy to clipboard operation
graphql-code-generator copied to clipboard

PreResolveTypes: true with template MaybeValues is broken

Open EDjur opened this issue 5 months ago • 0 comments

Which packages are impacted by your issue?

@graphql-codegen/typescript-operations

Describe the bug

Description If I use a template MaybeValue like suggested here

const config: CodegenConfig = {
   // ...
   generates: {
     'path/to/file.ts': {
       plugins: ['typescript'],
       config: {
         maybeValue: 'T extends PromiseLike<infer U> ? Promise<U | null> : T | null'
       },
     },
   },
 };

And I use the default preResolveTypes: true then the generated types will be broken for simple queries.

Your Example Website or App

https://stackblitz.com/edit/github-55hzb3?file=codegen.ts,document.graphql,schema.graphql,types.ts

Steps to Reproduce the Bug or Issue

Given this schema:

interface AB {
 id: String!
}

type AConfig {
 key: String!
}

type BConfig {
 value: String!
}

type A implements AB {
 id: String!
 config: AConfig!
}

type B implements AB {
 id: String!
 config: BConfig!
}

type Query {
 ab(id: String!): AB
}

And this operation:

query GetAB($id: String!) {
  ab(id: $id) {
    id

    ... on A {
      config {
        key
      }
    }

    ... on B {
      config {
        value
      }
    }
  }
}

And this codegen-config:

import type { CodegenConfig } from "@graphql-codegen/cli";

const config: CodegenConfig = {
  overwrite: true,
  schema: "schema.graphql",
  documents: ["./operations"],
  generates: {
    "src/generated/graphql.ts": {
      plugins: ["typescript", "typescript-operations", "typescript-resolvers"],

      config: {
        maybeValue:
          "T extends PromiseLike<infer U> ? Promise<U | null | undefined> : T | null | undefined",
        omitOperationSuffix: true
      },
    },
  },
};

export default config;

Then the generated type for the query operation defined above will be generated as:

export type GetAb = {
    __typename?: 'Query';
    ab?:
        | {
              __typename?: 'A';
              id: string;
              config: { __typename?: 'AConfig'; key: string };
          }
        | {
              __typename?: 'B';
              id: string;
              config: { __typename?: 'BConfig'; value: string };
          } extends PromiseLike<infer U>
        ? Promise<U | null | undefined>
        : T | null | undefined;
};

But ab here resolves to any because T is not defined (since it has preResolved the types and removed the Maybe wrapper.

If I instead set preResolveTypes: false, it works as expected (but I expect this to work with the default values too).

Expected behavior

I expected ab not be resolved to any when preResolveTypes: true is set.

Screenshots or Videos

No response

Platform

  • OS: macOS
  • NodeJS: 18.20.3 (but doesnt really matter)
  • graphql version: 16.2.0
  • @graphql-codegen/* version(s): 4.0.1

Codegen Config File

import { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  schema: 'schema.graphql',
  documents: 'document.graphql',
  generates: {
    'types.ts': {
      plugins: ['typescript', 'typescript-operations'],
      config: {
        maybeValue:
          'T extends PromiseLike<infer U> ? Promise<U | null | undefined> : T | null | undefined',
        omitOperationSuffix: true,
      },
    },
  },
};

export default config;

Additional context

No response

EDjur avatar Sep 23 '24 11:09 EDjur