Skip to content

Class and Enum Typings for Handling Data with GraphQL

Intro

Today we’ll talk about class and enum typings for handling more complex data with GraphQL. The typings will be used on class objects to make them easier to read and understand. This blog will build on the concepts of another blog found here, in which I discussed wrapping and enhancing data, which talks about how to create a GraphQL Rest API wrapper, and how to enhance your data.

This article assumes you have a basic understanding of classes, typing, and enums. Here is the code repo if you want to review it while reading, or just skip ahead. With that said, we will look at the class structure we’re going to be using, the enums, and the type lookup for our customField enum with our mapper.

Class setup

This class we’re going to set up will be strictly for typing. We’re going to make a RestaurantGuest class as this data will be restaurant themed. So in our restaurant.ts file, we will name it RestaurantGuest, and include a few different items.

Basic starting class example

  class RestaurantGuest {
    id!: number;
    name!: string;
    email!: string;
    phoneNumber!: string;
    /** foodReservation */
    3249258!: { id: number, value: string } | undefined;
  }

After setting that up, we will add a type that will reference the above class.

Type example

type RestaurantGuestResponse= {
 [g in keyof RestaurantGuest ]: RestaurantGuest [g];
};

This type will be used later when we do the type lookup in conjunction with our mapper function. With the above finished, we can now move on to handling our enums.

Handling enums

We’ll now create our Enum to make dealing with our complex data easier. Since the above 3249258 represents FoodReservation, we will create an enum for it. Now you might be wondering why 3249258 represents FoodReservation. Unfortunately, this is an example of how data can be returned to us from a call. It could be due to the field id established in a CMS such as Contentful, or from another source that we don’t control. This isn’t readable, so we’re creating an Enum for the value.

Enum example

export enum FoodReservation {
  'Yes' = 53425867,
  'No' = 53425868,
}

This will be used later during our type look-up.

Type lookup

Now we can start combining the enum from above with our class type, and a look-up type that we’re about to create. So let's make another type called RestaurantGuestFieldLookup, which will have an id and value.

Look-up type example

export type RestaurantGuestFieldLookup<
 TId extends string | number | null,
 TValue extends string | null
> = {
 id: TId;
 value: TValue;
};

Perfect, now we’ll swap out
3249258?: {id: number, value: string} | undefined;

to be
 3249258?: RestaurantGuestFieldLookup<
   FoodReservation,
   keyof typeof FoodReservation
 >;

We can now move on to creating and using our mapper. In a separate file called mapper.ts, we will create our restaruantGuestMapper function.
export const restaruantGuestMapper = (guest: RestaurantGuestResponse) => {
 if (!guest) {
   return null;
 }

 return {
   id: guest.id,
   name: guest.name,
   phoneNumber: guest.phoneNumber,
   email: guest.email,
   reservation: guest.3249258.id === FoodReservation.Yes,
 };
};

Tada! Thanks to all the work above, we can easily understand and get back the data we need.

Conclusion

Today's article covered setting up a typing class, creating an enum, and type lookup with a mapper for more complex data handling with GraphQL. Hopefully, the class structure was straightforward and helpful, along with the enums and type lookup and formatting examples.

If you want to learn more about GraphQL, read up on our resources available at graphql.framework.dev.