Skip to content

client-preset with documentMode: 'string' does not compile with Typescript's "noPropertyAccessFromIndexSignature": true #10550

@Ionshard

Description

@Ionshard

Which packages are impacted by your issue?

@graphql-codegen/client-preset

Describe the bug

When using the client preset to generate Typescript using documentMode: 'string'. Then typescript has errors in the fragment-masking.ts file when compiled with "noPropertyAccessFromIndexSignature": true

Your Example Website or App

N/A

Steps to Reproduce the Bug or Issue

N/A

Expected behavior

When generating a client with string documentMode I expect to get not Typescript errors.

Screenshots or Videos

No response

Platform

N/A

Codegen Config File

No response

Additional context

The errors are on the lines generated by these 2 lines:
https://github.com/dotansimha/graphql-code-generator/blob/master/packages/presets/client/src/fragment-masking-plugin.ts#L93-L94

However, generating without documentMode: 'string' the resulting code is fine. The normal generation function uses a different style of accessing __meta__:
https://github.com/dotansimha/graphql-code-generator/blob/master/packages/presets/client/src/fragment-masking-plugin.ts#L109

I tested using the same technique for accessing the entries out of __meta__ used in the regular mode inside the isStringDocumentMode conditional and it works fine. So it appears the solution has already been implemented for the regular mode and simply needs to be copied to the string document mode solution.

I have used patch-package on my project to get this working:

diff --git a/node_modules/@graphql-codegen/client-preset/cjs/fragment-masking-plugin.js b/node_modules/@graphql-codegen/client-preset/cjs/fragment-masking-plugin.js
index 9f466a6..0bf89f6 100644
--- a/node_modules/@graphql-codegen/client-preset/cjs/fragment-masking-plugin.js
+++ b/node_modules/@graphql-codegen/client-preset/cjs/fragment-masking-plugin.js
@@ -80,8 +80,8 @@ export function isFragmentReady<TQuery, TFrag>(
   fragmentNode: TypedDocumentString<TFrag, any>,
   data: FragmentType<TypedDocumentString<Incremental<TFrag>, any>> | null | undefined
 ): data is FragmentType<typeof fragmentNode> {
-  const deferredFields = queryNode.__meta__?.deferredFields as Record<string, (keyof TFrag)[]>;
-  const fragName = fragmentNode.__meta__?.fragmentName as string | undefined;
+  const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__?.deferredFields;
+  const fragName = (fragmentNode as { __meta__?: { fragmentName: string | undefined } }).__meta__?.fragmentName;
 
   if (!deferredFields || !fragName) return true;
 
diff --git a/node_modules/@graphql-codegen/client-preset/esm/fragment-masking-plugin.js b/node_modules/@graphql-codegen/client-preset/esm/fragment-masking-plugin.js
index bc2999a..aa115b6 100644
--- a/node_modules/@graphql-codegen/client-preset/esm/fragment-masking-plugin.js
+++ b/node_modules/@graphql-codegen/client-preset/esm/fragment-masking-plugin.js
@@ -77,8 +77,8 @@ export function isFragmentReady<TQuery, TFrag>(
   fragmentNode: TypedDocumentString<TFrag, any>,
   data: FragmentType<TypedDocumentString<Incremental<TFrag>, any>> | null | undefined
 ): data is FragmentType<typeof fragmentNode> {
-  const deferredFields = queryNode.__meta__?.deferredFields as Record<string, (keyof TFrag)[]>;
-  const fragName = fragmentNode.__meta__?.fragmentName as string | undefined;
+  const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__?.deferredFields;
+  const fragName = (fragmentNode as { __meta__?: { fragmentName: string | undefined } }).__meta__?.fragmentName;
 
   if (!deferredFields || !fragName) return true;

I have not created a reproduction example because there is an example of working code just 16 lines down in the exact file. There is not really a need to further debug this issue since it has already been solved for the normal mode. If you'd like me to build it regardless of this, then simply ask and I will.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions