diff --git a/packages/plugins/typescript/typed-document-node/src/config.ts b/packages/plugins/typescript/typed-document-node/src/config.ts index a4de17d9ec2..5dd1d16eb96 100644 --- a/packages/plugins/typescript/typed-document-node/src/config.ts +++ b/packages/plugins/typescript/typed-document-node/src/config.ts @@ -48,4 +48,31 @@ export interface TypeScriptTypedDocumentNodesConfig extends RawClientSideBasePlu * ``` */ addTypenameToSelectionSets?: boolean; + + /** + * @description Allows you to import the operation types from a different file. + * @default "" + * + * @exampleMarkdown + * ```ts filename="codegen.ts" + * import type { CodegenConfig } from '@graphql-codegen/cli'; + * + * const config: CodegenConfig = { + * // ... + * generates: { + * 'path/to/file.ts': { + * plugins: ['typescript', 'typescript-operations'] + * }, + * 'path/to/file2.ts': { + * plugins: ['typed-document-node'], + * config: { + * importOperationTypesFrom: 'path/to/file.ts' + * }, + * }, + * }, + * }; + * export default config; + * ``` + */ + importOperationTypesFrom?: string; } diff --git a/packages/plugins/typescript/typed-document-node/src/visitor.ts b/packages/plugins/typescript/typed-document-node/src/visitor.ts index 343c1d3ffe5..dc090ffb9aa 100644 --- a/packages/plugins/typescript/typed-document-node/src/visitor.ts +++ b/packages/plugins/typescript/typed-document-node/src/visitor.ts @@ -98,16 +98,19 @@ export class TypeScriptDocumentNodesVisitor extends ClientSideBaseVisitor< } protected getDocumentNodeSignature(resultType: string, variablesTypes: string, node) { + const shouldUseImportPrefix = !!this.config.importOperationTypesFrom; + const resultImportPrefix = shouldUseImportPrefix && resultType !== 'unknown' ? 'Types.' : ''; + const variablesImportPrefix = shouldUseImportPrefix && variablesTypes !== 'unknown' ? 'Types.' : ''; if ( this.config.documentMode === DocumentMode.documentNode || this.config.documentMode === DocumentMode.documentNodeImportFragments || this.config.documentMode === DocumentMode.graphQLTag ) { - return ` as unknown as DocumentNode<${resultType}, ${variablesTypes}>`; + return ` as unknown as DocumentNode<${resultImportPrefix}${resultType}, ${variablesImportPrefix}${variablesTypes}>`; } if (this.config.documentMode === DocumentMode.string) { - return ` as unknown as TypedDocumentString<${resultType}, ${variablesTypes}>`; + return ` as unknown as TypedDocumentString<${resultImportPrefix}${resultType}, ${variablesImportPrefix}${variablesTypes}>`; } return super.getDocumentNodeSignature(resultType, variablesTypes, node); diff --git a/packages/plugins/typescript/typed-document-node/tests/typed-document-node.spec.ts b/packages/plugins/typescript/typed-document-node/tests/typed-document-node.spec.ts index 6cf6ef5a35d..42764efdc45 100644 --- a/packages/plugins/typescript/typed-document-node/tests/typed-document-node.spec.ts +++ b/packages/plugins/typescript/typed-document-node/tests/typed-document-node.spec.ts @@ -77,4 +77,44 @@ describe('TypedDocumentNode', () => { expect((res.content.match(/__typename/g) || []).length).toBe(1); }); }); + + describe('addTypenameToSelectionSets', () => { + it('Should import Types from the given file', async () => { + const schema = buildSchema(/* GraphQL */ ` + schema { + query: Query + } + + type Query { + job: Job + } + + type Job { + id: ID! + } + `); + + const ast = parse(/* GraphQL */ ` + query { + job { + ...JobFragment + } + } + + fragment JobFragment on Job { + id + } + `); + + const res = (await plugin( + schema, + [{ location: '', document: ast }], + { importOperationTypesFrom: 'file.ts' }, + { outputFile: '' } + )) as Types.ComplexPluginOutput; + + expect((res.content.match(//g) || []).length).toBe(1); + expect((res.content.match(//g) || []).length).toBe(1); + }); + }); });