eddeee888 / graphql-code-generator-plugins

List of GraphQL Code Generator plugins that complements the official plugins.
MIT License
52 stars 13 forks source link

How to apply mappers only to the parent and not to the resolver's return type? #318

Closed szaim closed 1 month ago

szaim commented 4 months ago

In our graphql server there are essentially two types that exist in parallel.

  1. The resolver return type, generated by graphql-codegen
  2. The custom type existing internally before returning The custom types are the actual entities that exist within our application before them being exposed by graphql.

Question Is it possible to configure graphql-codegen to type the parent parameter of a resolver with an internal type while keeping the default resolver return type? Also the codegen preset library am using it keeps overriding my field resolvers

I followed this example below and the typing inside the userResolver now works. However, the type of the userResolvers itself when used in the const resolvers that is typed with Resolvers is not assignable to User. So the type error is only shifted one level. Am I missing something here? :

const userResolvers: UserResolvers<any, UserModel> = {
  email: (parent) => {
    parent
    // ^ of type `UserModel` (not the GraphQL one)
    return ''
  }
}

and here is my codegen config

import { defineConfig } from '@eddeee888/gcg-typescript-resolver-files';

const resolverConfig = defineConfig({
  mode: 'modules',
  emitLegacyCommonJSImports: false,
  //resolverGeneration: 'disabled',
  add: {
    './types.generated.ts': {
      content: ['// @ts-nocheck', '/* eslint-disable */', "import { DeepPartial } from 'utility-types';"],
    },
  },
  typesPluginsConfig: {
    contextType: '@/types/web-server.d.js#ServerContext',
    allowParentTypeOverride: true,
   // makeResolverTypeCallable: true,
    // Makes the info argument passed to the resolver functions optional.
    optionalInfoArgument: true,
    //avoidOptionals: true,
    maybeValue: 'T | null | undefined',
    inputMaybeValue: 'T | null | undefined',
    defaultMapper: 'DeepPartial<{T}>',

  },

})
eddeee888 commented 3 months ago

Hi @szaim ,

At runtime, the parent's returned value will go into the parent param of the Object type. Therefore, the two should match otherwise you may get runtime error.

Is it possible to configure graphql-codegen to type the parent parameter of a resolver with an internal type while keeping the default resolver return type?

Unfortunately, I haven't seen a use case for this. The current way preset works enforces the way GraphQL works - in my understanding - to help users avoid runtime errors. Are you observing something different in your application?

Also the codegen preset library am using it keeps overriding my field resolvers

Yes, this is expected to prevent users from using generated types incorrectly that could lead to type-safety issues.

eddeee888 commented 1 month ago

Closing this as it is behaving as expected