Skip to content

Allow result type and variables type to be inferred from DocumentNode/Source using TypeScript type system #2727

Closed
@dotansimha

Description

@dotansimha

Hi!

We recently implemented an improved version of DocumentNode, called TypedDocumentNode, that allow type generics for result type and variables type:

export interface TypedDocumentNode<Result = { [key: string]: any }, Variables = { [key: string]: any }> extends DocumentNode {}

This improved version allows TypeScript to infer the types automatically when an object that matches the signature is used, for example:

const typedDocument: TypedDocumentNode<{ test: string }, { v: string }> = parse(`query($v: String) { test(v: $v) }`);

// Now `result` will be automatically of type `{ test: string }`
const result = await execute({
  // ...
  document: typedDocument,
  // variableValues will be typed to `{ v: string }` automatically
  variableValues: { v: 'test' },
});

This will allow to have the types set within the DocumentNode and not externally as used today, and avoid incorrect TypeScript types used.
This made possible because TypeScript does type inference when possible.

The existing solution is implemented in this repo: https://github.com/dotansimha/graphql-typed-document-node and it's currently implemented by patching graphql library and add support to it. I think this concept could be merged into this PR, just like we allow extensions or other to be typed with generics.

Developers who chose to automate the typings creation, can use GraphQL Code Generator to generate a pre-compiled DocumentNode<T, R> from their operations, the output file looks like that:

https://github.com/dotansimha/graphql-typed-document-node/blob/master/examples/graphql/typed-document-nodes.ts#L45

Adding this to the core implementation of graphql won't break anything, since it effects only TypeScript types, and the generics are mostly there today, so it's just a few non-breaking adjustments to support this.

To have it fully supported across graphql and execute method, it needs to be added to Source and DocumentNode. I created a PR here: #2728

Related:

@IvanGoncharov

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions