Typescript types for resolvers

Hey @Conny_Gu :wave:!

parent, args and contextValue you’ll need to type yourself since they are dependent on your schema and your setup.

parent
This value should be whatever you return from a parent resolver. For example, let’s say your schema looks something like this:

query {
  currentUser: User
}

type User {
  firstName: String
}

And that you’re trying to resolve User.firstName in this query:

query {
  currentUser {
    firstName
  }
}

In this case, the parent type should be equal to the TypeScript type returned from your currentUser resolver. Let’s call that TypeScript User. Your parent value would look something like this:

import { User } from './types.ts' // or whenever you store this type

const resolvers = {
  User: {
    firstName: (parent: User) => {
      // ...
    }
  }
}

In your example above, since you’re trying to resolve a top-level Query field, the value is going to depend on whether you pass a rootValue option to your ApolloServer constructor. If you’ve passed a value to rootValue, then parent is going to be the same type as rootValue. If not, then any or never will likely suit you just fine since you’re likely not going to use that value.

args

This type will depend on your schema and whether the field you’re trying to resolve takes arguments or not. If your field takes no arguments, any or never should work just fine here. If you do, the object type should match the types in your schema. for example:

# schema.graphql
type Query {
  posts(limit: Int!): [Post!]!
}
interface QueryPostsArgs {
  limit: number
}

const resolvers = {
  Query: {
    posts: (parent: any, args: QueryPostsArgs) => {
      // ...
    }
  }
}

contextValue
This type is going to depend on whether you pass a context function to the ApolloServer constructor. If you don’t pass context, then any or never is going to be ok here. If you do, the value should match what you return from that function. See the “Sharing Context” docs for an example of how you use context.

info
You can type this with the GraphQLResolveInfo imported from the graphql package.

import { GraphQLResolveInfo } from 'graphql';

Using your example above it will look something like this:

import { GraphQLResolveInfo } from 'graphql';
import { RootValue, ContextValue } from './types'; // or wherever you store these types

interface QueryCurrentUserArgs {
  // empty for now since I don't know if your schema takes args here
}

const resolvers = {
  Query: {
    // Our resolvers can access the fields in contextValue
    // from their third argument
    currentUser: (
      parent: RootValue, 
      args: QueryCurrentUserArgs, 
      contextValue: ContextValue, 
      info: GraphQLResolveInfo
    ) => {
      return contextValue.dataSources.userApi.findUser(contextValue.token);
    },
  },
};

Hope that helps!

1 Like