Override from GraphQL Schema generated Typescript types

2.8k views Asked by At

Im using the graphql-code-generator to generate typescript types out of my GraphQL schema. In GraphQL you can create custom scalar types which will generate the following type: /graphql.ts

export type Scalars = {
  String: string;
  Boolean: boolean;
  NodeDescription: any;
};

export type CodeResource = {
  ast: Scalars["NodeDescription"];
};

As you can see the GraphQL default scalar types like String, Boolean etc. will be mapped on the equivalent Typescript type. Custom scalar types like NodeDescription will get the typescript type any.

In my Angular Client there already is a NodeDescription type (in ../app/shared/syntaxtree) which I want to use instead of the generated any type. Is there a way to override the NodeDescription field in Scalars type? So in the end I want the ast field of the generated CodeResource type to have the type NodeDescription instead of any.

My first idea was to override the the Scalars["NodeDescription"] type with NodeDescription. So I tried to import all types in a new file and override them like: /types.ts

import {Scalars} from "./graphql";
import {NodeDescription} from "../app/shared/syntaxtree";
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
type Scalar = Overwrite<Scalars, {NodeDescription: NodeDescription}>

This actually works, but the ast field of the CodeResource type still is type any.

Another idea is to use a bash script with a well thought out sed command so the generated file will be edited like:

import {NodeDescription} from "../app/shared/syntaxtree";
export type Scalars = {
  String: string;
  Boolean: boolean;
  NodeDescription: NodeDescription;
};

However before I implement that approach I would like to know if there is a smart typescript way to override the generated types. Thanks for help.

1

There are 1 answers

0
Yannick Schröder On BEST ANSWER

I found a specific solution if you have the same problem using graphql-code-generator. There is a plugin called add. So in the codegen.yml you are able to add imports and address the custom scalar types. My codegen.yml now looks like that:

overwrite: true
schema: "../schema/graphql/schema.json"
documents: "../schema/graphql/**/*.graphql"
generates:
  src/generated/graphql.ts:
    plugins:
      - "typescript"
      - "typescript-operations"
      - "typescript-apollo-angular"
      - add:
          content: 'import { NodeDescription } from "../app/shared/syntaxtree";'
    config:
      enumsAsTypes: true
      scalars:
        NodeDescription: NodeDescription
        ISO8601DateTime: string