Describe the bug
When generating for a backend server, required arguments with default values are marked as optional in the generated types. I would expect a arguments with defaults to be optional on clients, but on the server these values will always be set since they will either have a default or would be explicitly set by the client request.
Seems identical to and earlier issue: https://github.com/dotansimha/graphql-code-generator/issues/2064
To Reproduce
Steps to reproduce the behavior:
Reproduced in the following sandbox. Look at incorrectTypedArg being given as an argument to the user query.
https://codesandbox.io/s/graphql-codegen-issue-template-bpun1
Expected behavior
I would expect incorrectTypedArg to be marked as non-optional in the generated types:
export type QueryUserArgs = {
id: Scalars["ID"];
incorrectTypedArg: Scalars["Int"];
};
Environment:
@graphql-codegen/...: 1.8.2Hi @Tybot204 ,
The QueryUserArgs is defined as optional, but if you'll take a look at the resolver signature, you'll see that we override it to make it non-optional:
RequireFields<QueryUserArgs, 'id' | 'incorrectTypedArg'>
The reason is works this way, is because typescript plugin generates types as base types. From a client side perspective, a variable with default value is optional, but from a server side perspective, it's non-optional. We decided to keep the original Args type as-is, and change it during the creation of resolvers signature.
Use the resolvers signature on a high-level variable, and you won't need to add QueryUserArgs explicitly:
const resolvers: Resolvers = {
Query: {
user: (root, args, context, info) => {
args.incorrectTypedArg // this is now non-optional, no need to specify `QueryUserArgs` explicitly
}
}
};
Hi @dotansimha,
Should this also work for nested values?
Say we have something like this:
input CorrectlyTypedInput {
nestedIncorrectInput: Int = 10
}
type RootMutation {
veryCoolMutation(input: CorrectlyTypedInput = {}): Boolean!
}
The input argument is non-optional, but the nestedIncorrectInput is still optional, which doesn't make sense for the server. It's mitigated by optional chaining, but can be annoying for non-trivial stuff.
const RootMutation: RootMutationResolvers = {
veryCoolMutation: async (_, {input}) => {
return input.nestedIncorrectInput?.toString(10) === "1";
}
}
I'm not 100% sure. @edgarnansen if it's still relevant and causes issues for you, can you please report it in a new issue?
Most helpful comment
Hi @Tybot204 ,
The
QueryUserArgsis defined as optional, but if you'll take a look at the resolver signature, you'll see that we override it to make it non-optional:The reason is works this way, is because
typescriptplugin generates types as base types. From a client side perspective, a variable with default value is optional, but from a server side perspective, it's non-optional. We decided to keep the originalArgstype as-is, and change it during the creation of resolvers signature.Use the resolvers signature on a high-level variable, and you won't need to add
QueryUserArgsexplicitly: