Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Federation Resolvers: Pick<ParentType, 'fieldName'> is incorrect for mapped parent types. #3207

Open
Tracked by #8296 ...
bsmedberg-xometry opened this issue Jan 2, 2020 · 5 comments
Assignees
Labels

Comments

@bsmedberg-xometry
Copy link

Describe the bug

When using typescript-resolvers with federation: true. The generated code for the resolver uses the following type for the resolver:

  __resolveReference: ReferenceResolver<Maybe<IResolversTypes['User']>, { __typename: 'User' } & Pick<ParentType, 'id'>, ContextType>,

However, when combined with a mapped type, this code is incorrect. ParentType is the mapped object, which may not have an id property at all, or its id property may be a completely unrelated type.

To Reproduce
Steps to reproduce the behavior:

  1. My GraphQL schema:
type User @key(fields: "id') {
  id: ID!
  name: String
}
  1. My codegen.yml config file:
schema: "src/schema.ts"
documents: null
generates:
  src/generated/schema.ts:
    plugins:
      - "typescript"
      - "typescript-resolvers"
    config:
      avoidOptionals: true
      immutableTypes: true
      mappers:
        # Map GraphQL types in your schema to typescript types that are returned by resolvers and passed to child resolvers.
        User: ../user#User
      useIndexSignature: true
      typesPrefix: "I"
      federation: true
  1. My User and resolver types:
export class User {
    _id: string;
    name: string | null;
}

export UserResolver: IUserResolvers = {
    id: user => Buffer.from(`User-${user._id}`, "ascii").toString("base64"),
    name: user => user.name,

    __resolveReference: (user) => {
        const decoded = new Buffer(user.id, "base64").toString("ascii");
        if (!decoded.startsWith("User-")) {
            throw new Error("Unexpected ID value.");
        }
        const userId = decoded.slice(5);
        return mongodb.users.findOne({_id: userId}) as User;
    },       
};

Expected behavior

My code should type-check correctly.

Actual behavior

Type '"id"' does not satisfy the constraint 'keyof ParentType'.

Environment:

  • OS: linux (docker container)
  • @graphql-codegen/cli@1.9.1
  • @graphql-codegen/introspection@1.9.1
  • @graphql-codegen/typescript@1.8.3
  • @graphql-codegen/typescript-resolvers@1.8.3
  • NodeJS: 12.13.0

Additional context

I am going to make a sample repo for this shortly, because the code samples above are artificial extractions from a larger running project.

@bsmedberg-xometry
Copy link
Author

I have now created an testcase repository showing this issue: https://github.com/bsmedberg-xometry/graphql-codegen-issue-3207-demo

I think I can provide a patch, which would be to replace this:

  __resolveReference: ReferenceResolver<Maybe<IResolversTypes['User']>, { __typename: 'User' } & Pick<ParentType, 'id'>, ContextType>,

with this:

  __resolveReference: ReferenceResolver<Maybe<IResolversTypes['User']>, { __typename: 'User' } & { id: IResolversTypes['Int'] }, ContextType>,

@bsmedberg-xometry
Copy link
Author

@kamilkisiela you seem to be involved in most of the federation issues, can you confirm whether my proposal is reasonable?

@jamesharv
Copy link

jamesharv commented Apr 9, 2020

Would appreciate a fix for this, as our generated code won't compile when using @key on types using mappers. Thanks for all the work done on this great tool.

@dallas-lbg
Copy link

I have come across this issue too. Any progress on a fix or preferred work around?

@dotansimha
Copy link
Owner

WIP here: #4232

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants