DEV Community

Cover image for How to convert a TypeScript built-in enum to a GraphQL enum
Samuel Durante for Woovi

Posted on

How to convert a TypeScript built-in enum to a GraphQL enum

At Woovi we are GraphQL lovers, hence we develop many helpers around this tool to bring a good developer experience.

A helper that we developed is graphqlEnumBuilder, this helper allows us to convert a TypeScript built-in enum into a GraphQLEnum without difficulty. Thus, if you add a new value in your TypeScript enum, you don't need to edit your GraphQL enum, because it's generated from your TypeScript enum.

How it works

enum Gender {
  Male = 'Male',
  Female = 'Female',
}

const GenderEnumType = graphqlEnumBuilder(
  'GenderType',
  Gender,
);
Enter fullscreen mode Exit fullscreen mode

When you call this GenderEnumType in some query or mutation as an argument and generate your schema file, note that the GenderEnumType is declared as an enum in the GraphQL notation.

Here is an example:

enum GenderType {
  Male
  Female
}
Enter fullscreen mode Exit fullscreen mode

Code solution

import { GraphQLEnumType } from 'graphql';

type EnumObject = {
  [index: string]: string;
};

type EnumObjectResult = {
  [index: string]: {
    value: string;
  };
};
export const enumBuilderValues = <T = EnumObject>(
  constants: T,
): EnumObjectResult =>
  Object.keys(constants).reduce(
    (prev, curr) => ({
      ...prev,
      [curr]: {
        value: constants[curr],
      },
    }),
    {},
  );

export const graphqlEnumBuilder = <T = EnumObject>(name: string, values: T) =>
  new GraphQLEnumType({
    name,
    values: enumBuilderValues(values),
  });
Enter fullscreen mode Exit fullscreen mode

Woovi is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.

If you want to work with us, we are hiring!


Photo by Tom Hermans on Unsplash

Top comments (6)

Collapse
 
kasir-barati profile image
Mohammad Jawad (Kasir) Barati

JFYI: We have scalar coercion in GraphQL, thus we normally do NOT need these steps or do we?

Discloser: I just started to learn GraphQL by reading their docs a few days ago. So thanks in advance for filling me in.

Ref: graphql.org/learn/execution/#scala...

Collapse
 
sibelius profile image
Sibelius Seraphini

it is up to your code, if you can do that without it, it is good.

Collapse
 
kasir-barati profile image
Mohammad Jawad (Kasir) Barati

BTW I am currently using NestJS + Apollo server. Do you have any exp with those? I know NestJS is a battle tested framework but IDK much about GraphQL and Apollo server, are they up to the task? What tech stack do you use in your daily work to build GraphQL APIs?

Thread Thread
 
sibelius profile image
Sibelius Seraphini

You can check our stack here github.com/sibelius/relay-workshop

koa, graphql-js

Collapse
 
rbuzatto profile image
rbuzatto

Curious thing, can't you use union types instead? Normally it's a superior choice compared to enums. I'm not familiar with graphql but I expected it would support union types 🤔.

A minor thing that it doesn't affect much. Overall, using reduce, you should mutate the accumulator rather than creating new copies. There's no need to create new copies, there are no side effects here, and you would hurt your performance if you had a large collection of data to iterate over.

Collapse
 
samueldurante profile image
Samuel Durante

Curious thing, can't you use union types instead? Normally it's a superior choice compared to enums. I'm not familiar with graphql but I expected it would support union types 🤔.

Unfortunately, in GraphQL you can't have a parameter in your mutation that is a Union Type. So if you want to limit your mutation parameter to allow only specific values, you use an Enum Type for this.

A minor thing that it doesn't affect much. Overall, using reduce, you should mutate the accumulator rather than creating new copies. There's no need to create new copies, there are no side effects here, and you would hurt your performance if you had a large collection of data to iterate over.

Yes, in this case, I used reduce because is more convenient for me, but the way you wrote it is actually more performative.