Enums
A GraphQL enum defines a fixed set of named values. builder.enumType returns a reference you can
use as a field or argument type.
Defining an enum
An array of strings uses the same values in GraphQL and in your resolvers:
import SchemaBuilder from '@pothos/core';
const builder = new SchemaBuilder({});
const LengthUnit = builder.enumType('LengthUnit', {
values: ['Feet', 'Meters'],
});
builder.queryType({
fields: (t) => ({
height: t.float({
args: {
unit: t.arg({ type: LengthUnit, required: true, defaultValue: 'Meters' }),
},
resolve: (_parent, { unit }) => (unit === 'Meters' ? 5 : 5 * 3.281),
}),
unit: t.field({
type: LengthUnit,
args: { value: t.arg({ type: LengthUnit, required: true }) },
resolve: (_parent, { value }) => value,
}),
}),
});
export const schema = builder.toSchema();Pothos infers the inline array as the literal values 'Feet' | 'Meters'. If you define the array
in a separate variable, use as const to retain those literal types.
{
height
feet: height(unit: Feet)
unit(value: Meters)
}{
"data": {
"height": 5,
"feet": 16.405,
"unit": "Meters"
}
}Enum literals in a query are unquoted names. When passing an enum in JSON variables, use a string
such as "Meters".
Descriptions and internal values
Use a values object to describe or deprecate individual values, or to map GraphQL names to different values in your application:
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' },
Unknown: { deprecationReason: 'Use a nullable species field instead.' },
},
});The keys are GraphQL names. An argument containing Northern reaches the resolver as
'camelopardalis'; returning 'camelopardalis' from a GiraffeSpecies field produces "Northern"
in the response. If value is omitted, the key is also the internal value. Deprecating a value
leaves it usable by clients.
TypeScript enums
If your application already uses a TypeScript enum, register it directly:
enum Diet {
HERBIVOROUS,
CARNIVOROUS,
OMNIVOROUS,
}
builder.enumType(Diet, { name: 'Diet' });
builder.queryField('diet', (t) =>
t.field({
type: Diet,
resolve: () => Diet.HERBIVOROUS,
}),
);The enum's keys become GraphQL value names. Resolvers receive and return the TypeScript enum's
values, including numeric values in this example. You can use either the TypeScript enum itself
or the reference returned by enumType as the field or argument type.
Objects with as const
You can also derive enum values from an existing object:
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 }]),
),
});Here the GraphQL names are sedan, suv, truck, and motorcycle, while resolvers use SEDAN,
SUV, TRUCK, and MOTORCYCLE. To use the object's values for both names and internal values,
replace the enum definition with:
const VehicleTypeEnum = builder.enumType('VehicleType', {
values: Object.values(VehicleType),
});To use the keys for both, use Object.keys(VehicleType). TypeScript types Object.keys as
string[], so the following assertion preserves the known keys of this local object:
const VehicleTypeEnum = builder.enumType('VehicleType', {
values: Object.keys(VehicleType) as (keyof typeof VehicleType)[],
});