Incomplete type annotation for apollo's KeySpecifier type
Which packages are impacted by your issue?
@graphql-codegen/typescript-apollo-client-helpers
Describe the bug
There is a disconnect i.e. a missing type between the type generated for <T>KeySpecifier and apollo's actual interface.
Your Example Website or App
https://codesandbox.io/s/bug-gqlgen-apollo-keyspecifier-type-mismatch-wgjgkj?file=/repro.ts
Steps to Reproduce the Bug or Issue
For example, considering the schema
type T {
Foo: String
Bar: String
}
After running the typescript-apollo-client-helpers, plugin, it would generate the following type policy for T:
export type TKeySpecifier = ('Foo' | 'Bar' | TKeySpecifier)[];
export type TFieldPolicy = { /* irrelevant to this issue */ };
Expected behavior
Considering the actual type shape for the keyFields property —which includes a function to generate a type's keyField— I would expect the following type annotation:
export type TKeySpecifier = ('Foo' | 'Bar' | TKeySpecifier | (o: Readonly<T>, context: KeyFieldsContext) => string)[];
Screenshots or Videos
No response
Platform
- OS: macOS
- NodeJS: 16.4
graphqlversion: 15.5.0@graphql-codegen/*version(s): 2.6.1
Codegen Config File
No response
Additional context
No response
I used the following Yarn patch to improve the typing around this. My patch could be improved by finding a better type for the first parameter to TKeySpecifier function.
diff --git a/cjs/index.js b/cjs/index.js
index f009aab1baac950f33fe342dd11fe640d9e95a01..4e2ee3591aeb839df8cf239c54b5cb8ba784114c 100644
--- a/cjs/index.js
+++ b/cjs/index.js
@@ -23,6 +23,7 @@ function generateTypePoliciesSignature(schema, config) {
const fieldsNames = Object.keys(type.getFields()).filter(f => !f.startsWith('__'));
const keySpecifierVarName = `${typeName}KeySpecifier`;
const fieldPolicyVarName = `${typeName}FieldPolicy`;
+ const fieldType = `{ [P in keyof ${fieldPolicyVarName}]: any }`;
perTypePolicies.push(`export type ${keySpecifierVarName} = (${fieldsNames
.map(f => `'${f}'`)
.join(' | ')} | ${keySpecifierVarName})[];`);
@@ -34,7 +35,7 @@ ${fieldsNames
return {
...prev,
[typeName]: `Omit<TypePolicy, "fields" | "keyFields"> & {
-\t\tkeyFields${config.requireKeyFields ? '' : '?'}: false | ${keySpecifierVarName} | (() => undefined | ${keySpecifierVarName}),
+\t\tkeyFields${config.requireKeyFields ? '' : '?'}: false | ${keySpecifierVarName} | ((o: Readonly<${fieldType}>, context: KeyFieldsContext) => undefined | ${keySpecifierVarName}),
\t\tfields?: ${fieldPolicyVarName},
\t}`,
};
@@ -55,6 +56,7 @@ ${fieldsNames
return {
prepend: [
`import ${config.useTypeImports ? 'type ' : ''}{ FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache';`,
+ `import { KeyFieldsContext } from '@apollo/client/cache/inmemory/policies'`,
],
content: [...perTypePolicies, rootContent].join('\n'),
};
diff --git a/esm/index.js b/esm/index.js
index 574a6119c6c10e6b840ac9ec77a18bd577225f94..a21b5858177daae49f5a5143617f6bbec6cd3738 100644
--- a/esm/index.js
+++ b/esm/index.js
@@ -19,6 +19,7 @@ function generateTypePoliciesSignature(schema, config) {
const fieldsNames = Object.keys(type.getFields()).filter(f => !f.startsWith('__'));
const keySpecifierVarName = `${typeName}KeySpecifier`;
const fieldPolicyVarName = `${typeName}FieldPolicy`;
+ const fieldType = `{ [P in keyof ${fieldPolicyVarName}]: any }`;
perTypePolicies.push(`export type ${keySpecifierVarName} = (${fieldsNames
.map(f => `'${f}'`)
.join(' | ')} | ${keySpecifierVarName})[];`);
@@ -30,7 +31,7 @@ ${fieldsNames
return {
...prev,
[typeName]: `Omit<TypePolicy, "fields" | "keyFields"> & {
-\t\tkeyFields${config.requireKeyFields ? '' : '?'}: false | ${keySpecifierVarName} | (() => undefined | ${keySpecifierVarName}),
+\t\tkeyFields${config.requireKeyFields ? '' : '?'}: false | ${keySpecifierVarName} | ((o: Readonly<${fieldType}>, context: KeyFieldsContext) => undefined | ${keySpecifierVarName}),
\t\tfields?: ${fieldPolicyVarName},
\t}`,
};
@@ -51,6 +52,7 @@ ${fieldsNames
return {
prepend: [
`import ${config.useTypeImports ? 'type ' : ''}{ FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache';`,
+ `import { KeyFieldsContext } from '@apollo/client/cache/inmemory/policies'`,
],
content: [...perTypePolicies, rootContent].join('\n'),
};