Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Tracked by #8296 ...
alexstrat opened this issue Jan 12, 2022 · 0 comments
Labels
core Related to codegen core/cli

Comments

@alexstrat
Copy link

alexstrat commented Jan 12, 2022

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 and supports promise values).

type BarConnection {
  totalCount: Int!
  edges: [BarEdge!]!
}
type Foo {
  bars: BarConnection!
}
type LazyBarConnection = {
  totalCount: Promise<number>;
  edges: Promise<BarEdge[]>;
}

const makeConnection = (): LazyBarConnection => {...}

const resolvers: Resolvers = {
  Foo: {
    // Types of property 'totalCount' are incompatible.
    // Type 'Promise<number>' is not assignable to type 'number'.
    bars: () => makeConnection()
  }
}

Describe the solution you'd like
By default, defaultMapper should be Resolvable<T> where Resolvable looks like this:

type MaybeInPromise<ValueType> = ValueType | Promise<ValueType>

type MaybeAsFuncResultOrPromise<ValueType> =
  | ValueType
  | MaybeInPromise<ValueType>
  // todo: explicit parameters typing
  | ((...args: unknown[]) => MaybeInPromise<ValueType>)

type ResolvableArray<ArrayType> = {
  [Key in keyof ArrayType]: Resolvable<ArrayType[Key]>
}
type ResolvableObject<ObjectType> = {
  [Key in keyof ObjectType]: MaybeAsFuncResultOrPromise<Resolvable<ObjectType[Key]>>
}

export type Resolvable<ValueType> = ValueType extends Array<any>
  ? ResolvableArray<ValueType>
  : ValueType extends {}
  ? ResolvableObject<ValueType>
  : MaybeInPromise<ValueType>

(Extracted from this comment)

Describe alternatives you've considered
I successfully use the option defaultMapper to wrap object types in a Resolvable<T>, 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Related to codegen core/cli
Projects
None yet
Development

No branches or pull requests

2 participants