Which packages are impacted by your issue?
@graphql-codegen/typescript-operations
Describe the bug
With importSchemaTypesFrom and inlineFragmentTypes: 'combine', a document that only spreads a
fragment gets an import type * as Types it never references. Under noUnusedLocals that fails the
build.
Reproduction
npm install
npm run generate
npm run typecheck
src/book.generated.ts(4,1): error TS6133: 'Types' is declared but its value is never read.
Two fragments, in separate files. Only Category selects the enum field:
# src/category.graphql
fragment Category on Category { id kind } # kind: CategoryKind!
# src/book.graphql
fragment Book on Book { id category { ...Category } }
src/category.generated.ts — import used, correct:
import type * as Types from '../types';
export type CategoryFragment = { id: string, kind: Types.CategoryKind };
src/book.generated.ts — import emitted, never referenced:
import { CategoryFragment } from './category.generated';
import type * as Types from '../types'; // <-- unused
export type BookFragment = { id: string, category: CategoryFragment };
Expected
No Types import in src/book.generated.ts, since nothing in the file refers to it.
Cause
TypeScriptDocumentsVisitor.getExternalSchemaTypeImports()
(packages/plugins/typescript/operations/src/visitor.ts) gates the import on _usedSchemaTypes:
const hasTypesToImport =
Object.values(this._usedSchemaTypes).filter(
value => value.type === 'GraphQLEnumType' || value.type === 'GraphQLInputObjectType',
).length > 0;
if (!hasTypesToImport) {
return [];
}
CategoryKind is used by the document, so this is true for both files. But used by the document
and named by the generated file are different, and only the second justifies an import.
_usedSchemaTypes cannot answer the second on its own: it also decides whether enum and input
definitions are generated locally, which must account for types reached through fragments.
Only inlineFragmentTypes decides which of the two applies:
inlineFragmentTypes |
BookFragment |
names Types? |
tsc |
'inline' (default) |
{ category: { id: string, kind: Types.CategoryKind } } |
yes |
passes |
'combine' |
{ category: CategoryFragment } |
no |
fails |
Your Example Website or App
https://stackblitz.com/edit/gdtmg1pc
Steps to Reproduce the Bug or Issue
Run npm generate in the repro
Expected behavior
It should not have unused imports
Screenshots or Videos
No response
Platform
| package |
version |
@graphql-codegen/cli |
7.2.0 |
@graphql-codegen/typescript-operations |
6.1.6 |
@graphql-codegen/near-operation-file-preset |
5.2.2 |
graphql |
16.11.0 |
typescript |
5.9.3 |
Codegen Config File
import type { CodegenConfig } from '@graphql-codegen/cli';
const config: CodegenConfig = {
schema: './schema.graphql',
documents: './src/**/*.graphql',
config: {
// Fragment types are referenced, not inlined. This is what makes the bug observable:
// a document that only spreads a fragment never names the schema-types namespace itself.
inlineFragmentTypes: 'combine',
},
generates: {
// Shared Input/Enum types, per the v6 migration guide's multi-file setup.
'./types.ts': {
plugins: ['typescript-operations'],
config: {
generateOperationTypes: false,
},
},
// Per-document operation types, importing the shared types from the file above.
'./src': {
preset: 'near-operation-file',
presetConfig: {
extension: '.generated.ts',
},
plugins: ['typescript-operations'],
config: {
importSchemaTypesFrom: './types.ts',
namespacedImportName: 'Types',
},
},
},
};
export default config;
Which packages are impacted by your issue?
@graphql-codegen/typescript-operationsDescribe the bug
With
importSchemaTypesFromandinlineFragmentTypes: 'combine', a document that only spreads afragment gets an
import type * as Typesit never references. UndernoUnusedLocalsthat fails thebuild.
Reproduction
Two fragments, in separate files. Only
Categoryselects the enum field:src/category.generated.ts— import used, correct:src/book.generated.ts— import emitted, never referenced:Expected
No
Typesimport insrc/book.generated.ts, since nothing in the file refers to it.Cause
TypeScriptDocumentsVisitor.getExternalSchemaTypeImports()(
packages/plugins/typescript/operations/src/visitor.ts) gates the import on_usedSchemaTypes:CategoryKindis used by the document, so this istruefor both files. But used by the documentand named by the generated file are different, and only the second justifies an import.
_usedSchemaTypescannot answer the second on its own: it also decides whether enum and inputdefinitions are generated locally, which must account for types reached through fragments.
Only
inlineFragmentTypesdecides which of the two applies:inlineFragmentTypesBookFragmentTypes?tsc'inline'(default){ category: { id: string, kind: Types.CategoryKind } }'combine'{ category: CategoryFragment }Your Example Website or App
https://stackblitz.com/edit/gdtmg1pc
Steps to Reproduce the Bug or Issue
Run
npm generatein the reproExpected behavior
It should not have unused imports
Screenshots or Videos
No response
Platform
@graphql-codegen/cli@graphql-codegen/typescript-operations@graphql-codegen/near-operation-file-presetgraphqltypescriptCodegen Config File