feat: override operation field types via directives
Description
Add directiveFieldMappings option to typescript-operations plugin to overriding operation field types via directives.
Related https://github.com/dotansimha/graphql-code-generator/issues/7356
I fixed @jenseng's implementation to follow master and pass tests.
Example
# codegen.yml
plugins:
config:
# You cannot control optional(`?`) with `directiveFieldMapping`.
# Setting `avoidOptionals` is recommended when defining directives that change nullability, such as `@nonNull` or `@required`.
avoidOptionals:
field: true #
directiveFieldMappings:
asString: AsStringTransform
nonNull: NonNullable
nonNullEntries:
type: NonNullable
entries: true
# GraphQL Schema
directive @asString on FIELD
directive @nonNull on FIELD
directive @nonNullEntries on FIELD
type User {
id: Int
username: String
emails: [String]
}
...
# GrpahQL operation document
query {
me {
id @asString @nonNull
username @nonNull
emails @nonNullEntries
}
}
// generated type
{
me: {
id: AsStringTransform<number>,
username: NonNullable<string | null>,
emails: Array<NonNullable<string | null>> | null,
}
}
Type of change
Please delete options that are not relevant.
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
Checklist:
- [x] I have followed the CONTRIBUTING doc and the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream modules
Further comments
- directive argument support is not included in the first release
- e.g.
@required(entries: true),@as(type: "boolean") - Because:
- the need to discuss the optimal configuration file design
- even if arguments are not supported, the minimum use case can be satisfied
- it can be implement later without breaking changes
- e.g.
🦋 Changeset detected
Latest commit: eea74b2d67b41c22f8578169826d031441f2128c
The changes in this PR will be included in the next version bump.
This PR includes changesets to release 39 packages
| Name | Type |
|---|---|
| @graphql-codegen/visitor-plugin-common | Minor |
| @graphql-codegen/typescript-operations | Minor |
| @graphql-codegen/flow | Patch |
| @graphql-codegen/flow-operations | Patch |
| @graphql-codegen/flow-resolvers | Patch |
| @graphql-codegen/java-apollo-android | Patch |
| @graphql-codegen/java-common | Patch |
| @graphql-codegen/java | Patch |
| @graphql-codegen/kotlin | Patch |
| @graphql-codegen/java-resolvers | Patch |
| @graphql-codegen/typescript-apollo-angular | Patch |
| @graphql-codegen/typescript-apollo-client-helpers | Patch |
| @graphql-codegen/typescript-document-nodes | Patch |
| @graphql-codegen/typescript-generic-sdk | Patch |
| @graphql-codegen/gql-tag-operations | Patch |
| @graphql-codegen/typescript-graphql-request | Patch |
| @graphql-codegen/typescript-jit-sdk | Patch |
| @graphql-codegen/typescript-mongodb | Patch |
| @graphql-codegen/typescript-msw | Patch |
| @graphql-codegen/typescript-oclif | Patch |
| @graphql-codegen/typescript-react-offix | Patch |
| @graphql-codegen/typescript-react-apollo | Patch |
| @graphql-codegen/typescript-react-query | Patch |
| @graphql-codegen/typescript-resolvers | Patch |
| @graphql-codegen/typescript-rtk-query | Patch |
| @graphql-codegen/typescript-stencil-apollo | Patch |
| @graphql-codegen/typescript-type-graphql | Patch |
| @graphql-codegen/typed-document-node | Patch |
| @graphql-codegen/typescript | Patch |
| @graphql-codegen/typescript-urql-graphcache | Patch |
| @graphql-codegen/urql-svelte-operations-store | Patch |
| @graphql-codegen/typescript-urql | Patch |
| @graphql-codegen/typescript-vue-apollo-smart-ops | Patch |
| @graphql-codegen/typescript-vue-apollo | Patch |
| @graphql-codegen/typescript-vue-urql | Patch |
| @graphql-codegen/jsdoc | Patch |
| @graphql-codegen/graphql-modules-preset | Patch |
| @graphql-codegen/import-types-preset | Patch |
| @graphql-codegen/near-operation-file-preset | Patch |
Not sure what this means? Click here to learn what changesets are.
Click here if you're a maintainer who wants to add another changeset to this PR
@izumin5210 is attempting to deploy a commit to the The Guild Team on Vercel.
A member of the Team first needs to authorize it.
I wonder whether it instead would make sense that the field types are wrapped within a generic. That would allow more flexibility as well as allow chain ability of directives.
plugins:
config:
directiveFieldMappings:
asString: type AsStringTransform<_TIn> = string
nonNull: type NonNullTransform<TIn> = Exclude<TIn, null | undefined>
asBoolean: type AsBooleanTransform<_TIn> = boolean
query MeQuery {
me {
id @asBoolean @asString
}
}
type AsBooleanTransform<_TIn> = boolean
type Me = {
__typename?: 'User';
id: AsString<AsBooleanTransform<boolean>>;
};
Sorry for the delay in replying :bow:
I wonder whether it instead would make sense that the field types are wrapped within a generic. That would allow more flexibility as well as allow chain ability of directives.
I too think that is a great idea! I will update this pull request or create a new one!
I updated the codes and PR description! could you review them? :pray:
We talked about this a lot and came to the conclusion that this is an anti-pattern. If you want special handling for a field you should use a custom scalar instead. See https://github.com/dotansimha/graphql-code-generator/issues/1532
I am going to close this.