Hello,
I'm generating resolvers using resolvers template
gql-gen --template graphql-codegen-typescript-resolvers-template --config gql-gen.json --out __generated/resolver-types.ts -s src/graph-api/schema.graphql
(using no-namespaces version for babel-typescript)
Here's my query type:
type Query {
users: [User!]!
}
Here's my query resolver type:
export interface QueryResolvers<Context = RequestContext, TypeParent = never> {
users?: QueryUsersResolver<User[], TypeParent, Context>;
}
Here's how I use it:
export const Query: QueryResolvers = {
users: async (_parent, _args, ctx) => ctx.db.users()
};
Why is users field optional? The result of users query can't be null.
Am I missing something? If there's a reason for it to be optional, can we get an option to make it required?
I'd like to be notified by typescript if I don't implement a resolver that is required in my schema. Would be very helpful.
Thank you!
Hi @mcongy !
The field is declared as optional because otherwise you have to specify a single file, with a single object, that contains all the mutation/query fields resolvers.
We recommend to separate it and not to use a huge file for all your resolvers.
By using optionals, you can get IDE support and auto-complete, and you can separate the type fields resolvers to multiple files.
Once you implemented a field, you must implement the resolver function correctly, otherwise you'll get an error from TypeScript compiler.
@dotansimha I was using prismas graphqlgen before and really liked that it required every resolver to be defined. You immediately got feedback when you forgot to implement a resolver.
This feedback is entirely missing here.
People who want to have it optional could use the Partial type introduced in TypeScript 2.1
I agree, but it forces you to implement the entire type resolver in the same file and object, which is fine if you are building a POC or a small project, but not useful if you are splitting your implementation to modules.
If you wish, you can add the following to your declartion, and wrap the generated types:
type NonOptional<T> = { [P in keyof T]-?: T[P] };
Then use it:
const queryResolvers: NonOptional<QueryResolvers> = {
// ..
};
@P4sca1
I would prefer if it would be required by default and if you want to split it into modules, you use the already existing Partial type.
Guess that’s just personal preference.
Anyways, thank you for your answer! :)
@P4sca1 I added it in this PR: https://github.com/dotansimha/graphql-code-generator/pull/1534
Very nice, good job! 👏
Fixed in 1.0.3.
Hi, I'm facing the same situation as OP, it's mentioned in this issue that it has been resolved in v1.0.3 but I'm not sure what exactly was fixed – I still get all-optional QueryResolvers when I try this in v1.2.0.
I tried setting avoidOptionals to true (which seems to be one of the commits in the linked "Bug fixes for 1.0" PR #1534, specifically this one: https://github.com/dotansimha/graphql-code-generator/pull/1534/commits/8c52a7b7e0a2210cf25e5dbf9aeed4d8adbc8706), however, that did many changes to my generated files, most of them undesired.
For me, the best workaround is still https://github.com/dotansimha/graphql-code-generator/issues/893#issuecomment-474924086 but I agree with @P4sca1 that maybe it would be more intuitive if resolvers were typed more "predictably" by default (required field in the schema => required resolver).
Even if you want to keep the current behavior, it would be great to have a config to disable all-optional resolvers. As noted above, avoidOptionals is not that option (and in fact, I was confused by this option for a while – I thought I must be doing something wrong before reading the reasoning in this issue 😄).
As a small note, there's a built-in Required<T> type:
const queryResolvers: Required<QueryResolvers> = ...;
Most helpful comment
As a small note, there's a built-in
Required<T>type: