12

Type script is showing error not mentioning argument type for each arguments:

  Mutation: {
    createUser: (parent, args, context, info) =>{

    }

I can solve by using any type, but what are the correct types?

  Mutation: {
    createUser: (parent: any, args: any, context: any, info: any) =>{

    }

enter image description here

1
  • 1
    Shouldn't it be createUser: { resolve: (parent, args, context, info) => ? Specifying the types should be optional anyway. Commented Jun 4, 2021 at 0:36

1 Answer 1

14

If you enable all strict type-checking options in tsconfig.json, you should add TS type for everything.

Let's take a look at the type of resolver.

export declare type IFieldResolver<TSource, TContext, TArgs = Record<string, any>> = (source: TSource, args: TArgs, context: TContext, info: GraphQLResolveInfo & {
 mergeInfo: MergeInfo;
}) => any;

Resolver arguments:

parent - For resolvers of top-level fields with no parent (such as fields of Query, Mutation), this value is undefined. So the TS type is undefined

args - As you can see from the type, it must meet the type parameters in generic constraints Record<string, any>. Since the actual parameter is passed from the Graphql client, we need to define the Args type/interface for each resolver.

context - It's a generic parameter, we need to define the application context interface by ourselves.

info - The TS type already there GraphQLResolveInfo & { mergeInfo: MergeInfo }

An working example:

E.g.

import express from 'express';
import { ApolloServer, gql, MergeInfo } from 'apollo-server-express';
import { GraphQLResolveInfo } from 'graphql';

const app = express();

const typeDefs = gql`
  type User {
    email: String!
  }
  type Query {
    user: User
  }
  type Mutation {
    createUser(email: String!, password: String!): Boolean
  }
`;

export declare type IFieldResolver<TSource, TContext, TArgs = Record<string, any>> = (source: TSource, args: TArgs, context: TContext, info: GraphQLResolveInfo & {
 mergeInfo: MergeInfo;
}) => any;

type CreateUserArgs = {
  email: string;
  password: string;
};

interface AppContext {
  userService: UserService;
}

const resolvers = {
  Query: {},
  Mutation: {
    createUser: (
      parent: undefined,
      args: CreateUserArgs,
      context: AppContext,
      info: GraphQLResolveInfo & { mergeInfo: MergeInfo },
    ) => {
      console.log(parent);
      return context.userService.createUser(args.email, args.password);
    },
  },
};

interface UserService {
  createUser(email: string, password: string): boolean;
}
class UserServiceImpl {
  createUser(email: string, password: string) {
    return true;
  }
}
const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: {
    userService: new UserServiceImpl(),
  },
});
server.applyMiddleware({ app, path: '/graphql' });
app.listen(8080, () => console.log('Apollo server started at http://localhost:8080'));

package versions:

"typescript": "^3.9.6",
"apollo-server": "^2.15.1",
"graphql": "^14.6.0",

GraphQL Query in client-side:

mutation{
  createUser(email: "[email protected]", password: "1234")
}

Response:

{
  "data": {
    "createUser": true
  }
}

Logs in server-side:

Apollo server started at http://localhost:8080
undefined
Sign up to request clarification or add additional context in comments.

2 Comments

Seems to me that your context type is incorrect... What about datasources etc ? Do you know if there is a built in Context type ?
@ErnestJones If you have a new question, please ask a new question. Create a minimal, reproducible code example to explain your question

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.