Skip to content

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

Open
@bsmedberg-xometry

Description

@bsmedberg-xometry

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:

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.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions