question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TypeScript GraphQLObjectType and TArgs

See original GitHub issue

The TypeScript definitions currently specify a TArgs generic type on GraphQLObjectType which then flows into GraphQLObjectTypeConfig, GraphQLFieldConfigMap and GraphQLFieldMap.

All field resolver arguments on an object therefore have to have the same base type.

This, to me, is unexpected as each resolve function can have it’s own differing requirements as to what arguments and it makes it awkward to use types arguments as you need to specify something like any when creating the GraphQLObjectType instance. For example:

interface MySource { /* ... */ }
interface MyContext { /* ... */ }

interface MyFieldArgs {
    foo?: number;
    bar: string;
}

interface MyOtherFieldArgs {
    baz: string;
}

const MyType = new GraphQLObjectType<MySource, MyContext, any>({
    fields: {
        myField: {
            args: {
                bar: { type: new GraphQLNonNull(GraphQLString) },
                foo: { type: GraphQLInt },
            },
            resolve: (source, args: MyFieldArgs, context, info) => { /* ... */ },
            type: GraphQLString,
        },
        myOtherField: {
            args: {
                baz: { type: GraphQLString },
            },
            resolve: (source, args: MyOtherFieldArgs, context, info) => { /* ... */ },
            type: GraphQLString,
        },        
    },
    name: "My",
});

I suppose you could stick with the default TArgs type and then use a typescript user-defined type guard. However this is even more awkward and seems unnecessary given that we are specifying the arguments in the GraphQLFieldConfig and can be sure that graphql has already validated and asserted that the arguments match what we expect when it comes to calling the resolve function.


function isMyFieldArgs(o: any): o is MyFieldArgs {
    /* check everything ... */
    return true;
}

{
    // ...
    resolve: (source, args, context, info) => {
        if (!isMyFieldArgs(args)) {
            return undefined;
        }
        /* ... */
    },
}

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:10
  • Comments:10 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
williambaileycommented, Nov 5, 2020

Having just gone through the migration to v15 this is still an issue and arguebly worse since #2488.

Now we have GraphQLObjectType<TSource = any, TContext = any> so we can’t specify TArgs as any at the top level and have it propagate to the children which default to TArgs = { [key: string]: any }.

This then leads to the situation where your typescript failes to build when you try to have infered and typed TArgs in your resolvers with errors such as:

Type '{ [argName: string]: any; }' is missing the following properties from type 'MyImageRequestArgs': height, width ts(2322)
definition.d.ts(447, 3): The expected type comes from property 'fields' which is declared here on type 'Readonly<GraphQLObjectTypeConfig<MySourceObject, MyContextValue>>'

MyImageRequestArgs in this instance would look something like

interface MyImageRequestArgs {
    [argName: string]: any;
    height: number;
    width: number;
}

Our workaround at the moment is to patch the GraphQLFieldConfig definition with something like

--- a/node_modules/graphql/type/definition.d.ts
+++ b/node_modules/graphql/type/definition.d.ts
@@ -511,7 +511,7 @@
 export interface GraphQLFieldConfig<
   TSource,
   TContext,
-  TArgs = { [argName: string]: any }
+  TArgs = any
 > {
   description?: Maybe<string>;
   type: GraphQLOutputType;

I will continue to see if there is something else going on that i’m missing but thought i’d give a quick update to the ticket.

3reactions
dmastrorillocommented, Jul 6, 2021

Do we have an update on this? I using version 15.5.0 and still facing the aforementioned issue

Type 'GraphQLFieldResolver<undefined, Context, MutationSignupArgs>' is not assignable to type 'GraphQLFieldResolver<undefined, Context, { [argName: string]: any; }>'. Type '{ [argName: string]: any; }' is missing the following properties from type 'MutationSignupArgs': firstName, lastName, email

Read more comments on GitHub >

github_iconTop Results From Across the Web

Type resolution for GraphQLObjectType with different nested ...
Create a type with a discriminatory field by combining interfaces? 1 · Describe to typescript react component wrapper · 5 · rootReducer = ......
Read more >
Developers - TypeScript GraphQLObjectType and TArgs -
The TypeScript definitions currently specify a TArgs generic type on GraphQLObjectType which then flows into GraphQLObjectTypeConfig , GraphQLFieldConfigMap ...
Read more >
Easiest way to create GraphQL API for a TypeScript module
GraphQL is a popular API query language that offers more structured, performant and secure ways of accessing data from other services than ...
Read more >
graphql GraphQLObjectType TypeScript Examples
This page shows TypeScript code examples of graphql GraphQLObjectType. ... and arguments */ function getViewerOT<TSource, TContext, TArgs>( name: string, ...
Read more >
Perfect Guide of Code First GraphQL Server with ... - ITNEXT
from "graphql";export const postType = new GraphQLObjectType({ ... On the other hand, GraphQL.js itself does not generate TypeScript type ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found