dotansimha / dotansimha/graphql-code-generator

[typescript-resolvers] Resolvers' default result type should allow async and resolvable object values

Open
#7,358 0 comments 4 reactions 0 assignees View on GitHub
core
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.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.