Skip to content

Preset: near-operation-file extractAllFieldsToTypes handling of nested interfaces in type names  #10502

@Georgegriff

Description

@Georgegriff

Which packages are impacted by your issue?

@graphql-codegen/typescript-operations

Describe the bug

I've been trying to workthrough the hell that is migrating off the apollo codegen, we can get most of the way there with near-operation-file adjusting some imports and using extractAllFieldsToTypes but i think i've found a bug with extractAllFieldsToTypes and how it handles nested interfaces - types that have the same fields present.

I've created a reproduction repo: https://github.com/Georgegriff/graphql-codegen-repro/tree/main

Example query

export const GET_ANIMALS = gql`
  query GetAnimals {
    animals {
      name
      age
      species
      owner {
        name
        license
      }
    }
  }

In this example animal has two types a Cat and Dog (same fields) and Owner has two types Trainer & Veterinarian also with the same fields present.

I am deliberately not using .. on inline fragments to show the issue.

The types generated end up like this

export type GetAnimals_animals_Cat_owner_Trainer = { __typename: 'Trainer', name: string, license: string };

export type GetAnimals_animals_Cat_owner_Veterinarian = { __typename: 'Veterinarian', name: string, license: string };

export type GetAnimals_animals_Cat_owner = GetAnimals_animals_Cat_owner_Trainer | GetAnimals_animals_Cat_owner_Veterinarian;

export type GetAnimals_animals_Cat = { __typename: 'Cat', name: string, age: number, species: string, owner: GetAnimals_animals_Cat_owner };

export type GetAnimals_animals_Dog = { __typename: 'Dog', name: string, age: number, species: string, owner: GetAnimals_animals_Cat_owner };

export type GetAnimals_animals = GetAnimals_animals_Cat | GetAnimals_animals_Dog;

export type GetAnimals_Query = { animals: Array<GetAnimals_animals> | null };

See how GetAnimals_animals_Dog owner field is GetAnimals_animals_Cat_owner this is strange because that type is not specific to Cats its a general owner type that is common between the two.

I wonder if in this case the Interface name should be used in the typename? or no typename at all, i'm not sure.

Your Example Website or App

https://github.com/Georgegriff/graphql-codegen-repro

Steps to Reproduce the Bug or Issue

I've created a reproduction repo: https://github.com/Georgegriff/graphql-codegen-repro/tree/main

Expected behavior

The common types generated don't use one of the child types in their name

Screenshots or Videos

No response

Platform

-OS: macOs

  • NodeJS: [22
  • graphql version: [e.g. 16.3.0]
  • @graphql-codegen/* version(s):
  • "@graphql-codegen/cli": "^6.0.2",
    "@graphql-codegen/near-operation-file-preset": "^3.1.0",
    "@graphql-codegen/typescript": "^4.0.1",
    "@graphql-codegen/typescript-operations": "^4.0.1"

Codegen Config File

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

const config: CodegenConfig = {
  schema: "schema.json",
  documents: ["query.ts"],
  config: {
    preResolveTypes: true,
    namingConvention: "keep",
    avoidOptionals: {
      field: true,
    },
    nonOptionalTypename: true,
    skipTypeNameForRoot: true,
    extractAllFieldsToTypes: true,
    skipDocumentsValidation: {
      skipValidationAgainstSchema: true,
      ignoreRules: true,
      skipDuplicateValidation: true,
    },
    omitOperationSuffix: true,
  },
  generates: {
    "types/graphql-global-types.ts": {
      plugins: ["typescript"],
    },
    "types/": {
      preset: "near-operation-file",
      presetConfig: {
        baseTypesPath: "graphql-global-types.ts",
        folder: "./types",
      },
      plugins: ["typescript-operations"],
    },
  },
};

export default config;

Additional context

The issue is likely in packages/plugins/other/visitor-plugin-common/src/selection-set-to-object.ts but i can't see a clean fix, especially not one that might change generated types

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions