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

Unmasked breaks when using Tagged type #12266

Closed
Yunie08 opened this issue Jan 13, 2025 · 9 comments · Fixed by #12267 or #12270
Closed

Unmasked breaks when using Tagged type #12266

Yunie08 opened this issue Jan 13, 2025 · 9 comments · Fixed by #12267 or #12270

Comments

@Yunie08
Copy link

Yunie08 commented Jan 13, 2025

Issue Description

Problem

After upgrading from 3.11.8 to 3.12.4, we encountered an error in our update functions using ids returned in data:
image

The detailed error being:

Impossible to assign the type '{ readonly [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...strings: string[]) => string; indexOf: (searchString: string, position?: number | undefined) => number; ... 47 more ...; readonly [tag]: unknown; }' to type 'UUID'.
  Impossible d'assigner le type '{ readonly [x: number]: string; toString: () => string; charAt: (pos: number) => string; charCodeAt: (index: number) => number; concat: (...strings: string[]) => string; indexOf: (searchString: string, position?: number | undefined) => number; ... 47 more ...; readonly [tag]: unknown; }' to type 'string'.

Our approach

We dug a little bit and found out that Unmasked (more precisely UnwrapFragmentRefs ) type breaks when using Tagged from type-fest (see reproduction).

We always end up in the branch TData extends object true in UnwrapFragmentRefs, in our case TData[id].

export type UnwrapFragmentRefs<TData> = true extends IsAny<TData>
  ? TData
  : TData extends any
  ? string extends keyof TData
    ? TData
    : keyof TData extends never
    ? TData
    : TData extends {
        " $fragmentRefs"?: infer FragmentRefs;
      }
    ? UnwrapFragmentRefs<
        CombineIntersection<
          | Omit<TData, " $fragmentRefs">
          | RemoveFragmentName<
              NonNullable<
                NonNullable<FragmentRefs>[keyof NonNullable<FragmentRefs>]
              >
            >
        >
      >
    : TData extends object
    ?
	// branch we always end up into
	// TData[K] does not exist in our case (id: UUID)
	{
        [K in keyof TData]: UnwrapFragmentRefs<TData[K]>;
      }
    : TData
  : never;

Thank you for your attention, and don't hesitate to reach out if further information is needed.

Link to Reproduction

https://codesandbox.io/p/devbox/xenodochial-edison-yzsnvq?file=%2Fsrc%2Fbug_reproduction.ts%3A15%2C1&workspaceId=ws_Sfp3CZt4y22Usf7cvosyGL

Reproduction Steps

No response

@apollo/client version

3.12.4

@jerelmiller
Copy link
Member

Hey @Yunie08 👋

Would you be able to make that codesandbox public? Unfortunately I get a "Devbox not found" error when trying to open that link.

Thanks for the report! We'll see what we can do to address.

@Yunie08
Copy link
Author

Yunie08 commented Jan 13, 2025

Hi @jerelmiller,
Sorry about that, it should be better now !

@jerelmiller
Copy link
Member

@Yunie08 awesome thank you!

I really appreciate the detail you put into the reproduction as its immediately obvious what's happening here. What I think we're going to try and do is move the ContainsFragmentRefs check from MaybeMasked over to the Unmasked type so that we leave the TData type alone if you're not working with masked types to begin with.

That said, this would only work when working with unmasked types and would probably reappear if you adopt data masking in the future and start generating masked types using these tagged scalar types. I think the change to move ContainsFragmentRefs over is a good one and would fix the issue you have now but I'll noodle on the 2nd issue a bit more to see if we can come up with something that would work longer-term. I'll let you know when I have a PR build you can try out.

@jerelmiller
Copy link
Member

@Yunie08 I just opened #12267 that should address this issue. Can you try the following PR build to see if it fixes the type issue in your app?

npm i https://pkg.pr.new/@apollo/client@12267

@Yunie08
Copy link
Author

Yunie08 commented Jan 14, 2025

Hey @jerelmiller,
The changes in your PR seem to be fixing our type errors.
Thank you for your quick reply and fix !

Copy link
Contributor

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.

@jerelmiller
Copy link
Member

@Yunie08 I've got one more PR opened (#12270) that should handle tagged types when used with data masking. We'll get 3.12.6 out once this is merged. Thanks again for the report!

@jerelmiller
Copy link
Member

This has just been released in 3.12.6!

Copy link
Contributor

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
For general questions, we recommend using our Community Forum or Stack Overflow.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 14, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
2 participants