Get TypeScript types from my graphql schema in a custom resolver

Writing a custom resolver in typescript and I want to use the type returned from my gql query in my TypeScript return type.

For example, in my custom resolver I query for a Person

const Person = await ctx.api.gqlRequest(PERSON_QUERY)

This returns a row from the Person table, exactly as you’d expect. I then want to return this from my custom resolver. So my function’s return type looks like:

Promise<FunctionResult<{?}>>

I’m confused on how to get the Type to put as a generic here. I can’t just put Person, as that isn’t defined. I don’t want to spend time manually defining this Type, as it has many columns, and I’d have to manually update it everytime I add or remove a column.

So how do I get my typescript types from my graphql schema?

Even more, there should be a way to get these types in my frontend. But the typical tool used (graphql-codegen) doesn’t work, and returns each field as optional. This may be a question for another post though.

Hey Justin,

Welcome back to the community! Let me dig into this and see if I can find an answer. It’s certainly an interesting one since the awesome part of GraphQL is that your requests are usually very specific to just the fields you’re looking for with that request (ie. only a certain number of fields or even requests from multiple objects), but if you’re making a request that’s asking for the entire Person object I can see why this would be useful.

Hey @Justin
You are right - graphql-codegen tool is the best way to get types from schema, but you need @graphql-codegen/typescript and @graphql-codegen/typescript-operations package installed

Here is the basic codegen.yml file that you can use for generating types

schema: https://api.8base.com/<workspace_id>_<workspace_environment>
overwrite: true
generates:
  src/shared/graphql/__generated__/index.ts:
    documents: 'src/**/*.{ts,tsx}'
    plugins:
      - 'typescript'
      - 'typescript-operations'
    config:
      enumsAsTypes: true
hooks:
  afterOneFileWrite:
    - prettier --write

also you can configure your types generation like this

    config:
      immutableTypes: true
      maybeValue: T
      disableDescriptions: true
      scalars:
        Date: 'string'
        DateTime: 'string'
        Time: 'string'
        BigInt: 'BigInt'
        JSON: 'Record<string, unknown>'

PS: you can use it for fronted and backend, just configure it as you need

Hope this will help,

Igor form 8base

1 Like

I can suggest another solution that we use in our team:

  1. Install the typescript-generic-sdk plugin
npm install @graphql-codegen/typescript-generic-sdk -D
  1. Configure your codegen config
...
generates:
  src/shared/graphql/__generated__/index.ts:
    documents: 'src/**/*.{ts,tsx}'
    plugins:
      - 'typescript'
      - 'typescript-operations'
      - 'typescript-generic-sdk'
...
  1. Perform codegeneration

  2. Create a typescript file in a convenient location with the following content

import type { FunctionContext } from '@8base/functions-types';

import { getSdk } from 'path/to/__generated__';

export const gqlApi = (ctx: FunctionContext) => {
  return getSdk(ctx.api.gqlRequest);
};
  1. Finally, in your custom function, do the following
import type { FunctionContext, FunctionEvent, FunctionResponse } from '@8base/functions-types';

import { gqlApi } from 'path/to/file'

const someFunction = async (event: FunctionEvent, ctx: FunctionContext): Promise<FunctionResponse<any>> => {
  const api = gqlApi(ctx)

  const { queryData } = await api.QueryName(
    { ...someVariables },
    { checkPermissions: false }
  )

  ...
}
2 Likes