dotansimha / dotansimha/graphql-code-generator
[typescript-resolvers] Resolvers' default result type should allow async and resolvable object values
- Dominant language
- TypeScript
- Stars
- 11.3k
- Forks
- 1.4k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 23
Description
**Is your feature request related to a problem? Please describe.**
Without `mappers`, when resolving an object of which some values are promises instead of plain values, typing reports errors while the GraphQL execution is fine (GraphQL default resolver even [accepts a resolve function as value](https://github.com/graphql/graphql-js/blob/main/src/execution/execute.ts#L1005-L1021) and [supports promise values](https://github.com/graphql/graphql-js/blob/main/src/execution/execute.ts#L525-L528)).
```gql
type BarConnection {
totalCount: Int!
edges: [BarEdge!]!
}
type Foo {
bars: BarConnection!
}
```
```ts
type LazyBarConnection = {
totalCount: Promise;
edges: Promise;
}
const makeConnection = (): LazyBarConnection => {...}
const resolvers: Resolvers = {
Foo: {
// Types of property 'totalCount' are incompatible.
// Type 'Promise' is not assignable to type 'number'.
bars: () => makeConnection()
}
}
```
**Describe the solution you'd like**
By default, `defaultMapper` should be `Resolvable` where `Resolvable` looks like this:
```ts
type MaybeInPromise = ValueType | Promise
type MaybeAsFuncResultOrPromise =
| ValueType
| MaybeInPromise
// todo: explicit parameters typing
| ((...args: unknown[]) => MaybeInPromise)
type ResolvableArray = {
[Key in keyof ArrayType]: Resolvable
}
type ResolvableObject = {
[Key in keyof ObjectType]: MaybeAsFuncResultOrPromise>
}
export type Resolvable = ValueType extends Array
? ResolvableArray
: ValueType extends {}
? ResolvableObject
: MaybeInPromise
```
_(Extracted from [this comment](https://github.com/dotansimha/graphql-code-generator/issues/1219#issuecomment-504426941))_
**Describe alternatives you've considered**
I successfully use the option `defaultMapper` to wrap object types in a `Resolvable`, but the purpose of this issue is to make this behavior the default one because that's what GraphQL default execution would accept.
**Additional context**
#1219 started mentioning the issue and #1593 resulted in more options that allows alternative solutions.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.