graphql-code-generator icon indicating copy to clipboard operation
graphql-code-generator copied to clipboard

Decouple `typed-document-node` plugin from `typescript` and `typescript-operations`

Open ngregory-rbi opened this issue 3 years ago • 3 comments

Is your feature request related to a problem? Please describe.

The plugin typed-document-node is tightly coupled with typescript and typescript-operations. If one would want to generate their types in one file, their operations in another, and then finally their nodes in another, that is completely impossible using the typed-document-node plugin. ~~It appears it may be possible with the typescript-document-nodes plugin with some tweaking, but this really should not be the case.~~

Describe the solution you'd like

typed-document-node should be brought more in line with typescript-document-nodes as far as being able to be used in its own file. At the very least, the importOperationTypesFrom config option should be ported to the plugin.

Describe alternatives you've considered

  • Instead of having separate files for types, operations, and nodes, one could have a file for types and then a file for operations and nodes. This works, but still couples the plugin to, at the very least, typescript-operations.
  • ~~It appears typescript-document-node could be used with some config tweaking, although it is unclear what config options are required to get the intended result.~~ UPDATE: while importOperationTypesFrom is listed in the docs as an config option for typescript-document-node, it appears the plugin does nothing with it, thus it would not be able to cast the nodes to TypedDocumentNode, even if it imported it.

Additional context

Separating out, at the very least, types and nodes is important in many cases. With complex schemas, the generated types can get quite large, and when trying to import nodes from a file that includes all those types, some setups might struggle. Bundlers or other dynamic analysis may fail when trying to parse the import. Separating the runtime code from the type annotations solves this, as most bundlers and such are smart enough to not parse type-only files. Yes, my first alternative does separate those out mostly, but it still couples to typescript-operations.

ngregory-rbi avatar Sep 08 '22 16:09 ngregory-rbi

Ok, I found a solution... sorta:

{
    ...
    preset: 'import-types-preset',
    presetConfig: {
        typesPath: './operations',
        importTypesNamespace: 'Operations',
    },
    plugins: ['typed-document-node'],
    config: {
        typesPrefix: 'Operations.',
    },
    ...
}

I don't think this is how the typesPrefix config option was meant to be used, but it works. Not sure if this will break in the future.

ngregory-rbi avatar Sep 08 '22 17:09 ngregory-rbi

The docs for typescript-document-node list a config option called documentNodeImport with the following message:

Customize from which module will DocumentNode be imported from. This is useful if you want to use modules other than graphql, e.g. @graphql-typed-document-node

This seems to imply one could import TypedDocumentNode with that plugin. But there does not appear to be any options to add on the type parameters necessary to take advantage of it. In that case, why suggest it? Or am I mistaken?

ngregory-rbi avatar Sep 09 '22 15:09 ngregory-rbi