Search code examples
typescriptgraphqlapolloapollo-client

How can I manually map apollo custom scalars to client side types


How can I manually map apollo custom scalars to client side types?

I wan't to change the type which is associated with a Field Policy. (I am trying to essentially do this, i.e. manually add support for a custom scalar type). The value from the server is a string but I wan't to convert it to a JS Data (more specifically a luxon DateTime)

I have a schema like this:

export interface SomeType {
  __typename: "SomeType";
  created: GraphQLDateTime;
}

I have a field policy like this:

import { DateTime } from 'luxon'

const cache = new InMemoryCache({
    typePolicies: {
      SomeType: {
        fields: {
          created: {
            read: (created: string): DateTime => DateTime.fromISO(created)
          }
        }
      }
    }
  })

I have a graphqlScalars.d.ts type file to provide mapping of custom types to JS types:

type GraphQLDateTime = string

I am unable to switch my type definition file to something like as it causes import issues:

type GraphQLDateTime = DateTime

The problem is, the field resolver works as expected (i.e. it converts my ISO8601 string into a luxon DateTime) but the TS typing system (because of the graphqlScalars.d.ts type definition) expects created to be a string so DateTime typings are not available on it.

This is the typing of the read function:

export declare type FieldReadFunction<TExisting = any, TReadResult = TExisting> = (existing: SafeReadonly<TExisting> | undefined, options: FieldFunctionOptions) => TReadResult | undefined;

How can I manually map apollo custom scalars to client side types?


Solution

  • Referencing this TS issue I was able to manually map my type in the following way using import syntax:

    type GraphQLDateTime = import('@types/luxon').DateTime
    

    Now in my code created (that has been converted via a FieldPolicy is converted to the correct typing.