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.
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.
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.
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.
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, you can read up on some resources available at graphql.framework.dev.
I originally wrote this for This Dot Labs and the original post can be found here.