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

Reserved keywords naming conflict e.g. TypeScript's `Record`, GraphQL's `Subscription`

Open yuliswe opened this issue 2 years ago • 3 comments

Which packages are impacted by your issue?

@graphql-codegen/typescript-resolvers

Describe the bug

If you have a type named Subscription:

type Query {
  subscriptions: [Subscription]
}

type Subscription {
  name: String
}

The generated output becomes:

export type QueryResolvers<ContextType = any, ParentType extends ResolversParentTypes['Query'] = ResolversParentTypes['Query']> = {
  subscriptions?: Resolver<Maybe<Array<Maybe<ResolversTypes['Subscription']>>>, ParentType, ContextType>;
};

export type SubscriptionResolvers<ContextType = any, ParentType extends ResolversParentTypes['Subscription'] = ResolversParentTypes['Subscription']> = {
  name?: SubscriptionResolver<Maybe<ResolversTypes['String']>, "name", ParentType, ContextType>; // wrong
};

export type Resolvers<ContextType = any> = {
  Query?: QueryResolvers<ContextType>;
  Subscription?: SubscriptionResolvers<ContextType>;
};

This is wrong. The name field should be a Resolver instead of SubscriptionResolver.

Your Example Website or App

https://codesandbox.io/p/sandbox/youthful-fermat-cg7ppp?file=%2Ftypes.ts&selection=%5B%7B%22endColumn%22%3A30%2C%22endLineNumber%22%3A133%2C%22startColumn%22%3A10%2C%22startLineNumber%22%3A133%7D%5D

Steps to Reproduce the Bug or Issue

  1. Open the sandbox.
  2. Run yarn generate
  3. Go to the types.ts file and see the wrong type.

Expected behavior

The name field should be a Resolver instead of SubscriptionResolver.

Screenshots or Videos

No response

Platform

"@graphql-codegen/cli": "^2.16.4",
"@graphql-codegen/typescript": "^2.8.7",
"@graphql-codegen/typescript-resolvers": "^2.7.12",

Codegen Config File

schema: "./schema.graphql"
generates:
  types.ts:
    plugins:
      - "typescript"
      - "typescript-resolvers"

Additional context

No response

yuliswe avatar Jan 29 '23 21:01 yuliswe

+1. Also encountered this issue while working with billing code in a system as we have a subscription model. We didn't realize this was using the underlying SubscriptionResolver which still had the query function properly, but unintentionally avoided some type errors that should have been thrown in our code if we used a different name the the correct type definitions had been generated.

g-wittig avatar Mar 07 '23 19:03 g-wittig

You can solve this using two ways

  1. Use Codegen’s type name prefix/suffix config
generates:
  src/generated/graphql.ts:
    plugins:
      - typescript
      - typescript-resolvers
    config:
      typesPrefix: Gql

  1. Use a custom mappers override
config:
  mappers:
    Subscription: ./models#UserSubscriptionModel

kaushal-aubie avatar Nov 03 '25 13:11 kaushal-aubie

Hi all ! Thanks for reporting the issue. There are similar issues like this where, reserved keywords (could be by TypeScript e.g. Record, or GraphQL e.g. Subscription).

I'm thinking the high-level solution would be to have a config option to map keyword (reserved or not) to type names e.g.

typeNameTransform: {
  Record: 'Schema_Record', // `Record` is a TS keyword, this could be the default
  Subscription: 'Schema_Subscription', // `Subscription` is a GraphQL keyword , this could be the default
  User: '_User' // User is not a reserved keyword, so not the default. However, we could use this config map to change the type
}

However, this needs a bit thinking to make sure all relevant plugins can support it correctly. This will have dependency on https://github.com/dotansimha/graphql-code-generator/pull/10496 (our main focus atm).

eddeee888 avatar Nov 16 '25 03:11 eddeee888