Enums
Enums can be defined a number of different ways:
-
Using typescript enums
export enum Diet { HERBIVOROUS, CARNIVOROUS, OMNIVORIOUS, } builder.enumType(Diet, { name: 'Diet', });
-
Using an array of strings
export const LengthUnit = builder.enumType('LengthUnit', { values: ['Feet', 'Meters'] as const, });
Note that we use
as const
to allow ts to properly type our enum values. -
Using a values object:
export const GiraffeSpecies = builder.enumType('GiraffeSpecies', { values: { Southern: { description: 'Also known as two-horned giraffe', value: 'giraffa', }, Masai: { value: 'tippelskirchi', }, Reticulated: { value: 'reticulata', }, Northern: { value: 'camelopardalis', }, } as const, });
Again we use
as const
here to allow the enum values to be correctly inferred. Theas const
can also be added to the values instead, or omitted if thevalues
are already defined using a variable that typescript can type correctly.Using a values object like this enables defining additional options like a description for each enum value.
Using a values object also allows the name of the enum value to be different from the typescript value used internally in your resolvers.
The keys (eg
Southern
) are used as the name of the enum value in you GraphQL schema, and thevalue
(eg.'giraffa'
) property is used as the value you will receive in the arguments for your resolvers, or the value you need to return from your resolvers. This is similar to how typescript enum values can be assigned string or numeric values. -
Using an object with
as const
const VehicleType = { sedan: 'SEDAN', suv: 'SUV', truck: 'TRUCK', motorcycle: 'MOTORCYCLE', } as const; const VehicleTypeEnum = builder.enumType('VehicleType', { values: Object.fromEntries( Object.entries(VehicleType).map(([name, value]) => [name, { value }]), ), });
Modern TypeScript may prefer using objects with as const over enums to align with JavaScript standards. This approach essentially mirrors the "array of strings" method. You can use
Object.toEntries
andObject.fromEntries
to turn convert to Object values form described above.For more detailed information, you can refer to the TypeScript handbook on Objects vs Enums.
Alternatively, using
Object.keys
orObject.values
will allow you to produce an enum that uses just the keys or values of the object for both the internal typescript and name in the GraphQL schema.const VehicleType = { sedan: 'SEDAN', suv: 'SUV', truck: 'TRUCK', motorcycle: 'MOTORCYCLE', } as const; const VehicleTypeEnum = builder.enumType('VehicleType', { values: Object.values(VehicleType), }); // Or const VehicleTypeEnum = builder.enumType('VehicleType', { values: Object.keys(VehicleType) as (keyof typeof VehicleType)[], });
Using Enum Types
Enums can be referenced either by the Ref
that was returned by calling builder.enumType
or by
using the typescript enum. They can be used either as arguments, or as field return types:
builder.objectFields('Giraffe', (t) => ({
height: t.float({
args: {
unit: t.arg({
type: LengthUnit,
required: true,
defaultValue: 'Meters',
}),
},
resolve: (parent, args) =>
args.unit === 'Meters' ? parent.heightInMeters : parent.heightInMeters * 3.281,
}),
diet: t.field({
description:
'While Giraffes are herbivores, they do eat the bones of dead animals to get extra calcium',
type: Diet,
resolve: () => Diet.HERBIVOROUS,
}),
species: t.field({
type: GiraffeSpecies,
resolve: () => 'camelopardalis' as const,
}),
}));