Skip to main content

Enums

GraphQL enums can be defined by placing a @gqlEnum docblock directly before a:

  • TypeScript enum declaration
  • Type alias of a union of string literals
  • Type alias of a const-array member type query (for example typeof VALUES[number])
/**
* A description of my enum.
* @gqlEnum <optional name of the enum, if different from type name>
*/
enum MyEnum {
/** A description of my variant */
OK = "OK",
/** A description of my other variant */
ERROR = "ERROR",
}

Note that the values of the enum are used as the GraphQL enum values, and must be string literals.

To mark a variants as deprecated, use the @deprecated JSDoc tag directly before it:

/** @gqlEnum */
enum MyEnum {
OK = "OK"
/** @deprecated Please use OK instead. */
OKAY = "OKAY"
ERROR = "ERROR"
}

We also support defining enums using a union of string literals, however there are some limitations to this approach:

  • You cannot add descriptions to enum values
  • You cannot mark enum values as deprecated

This is due to the fact that TypeScript does not see JSDoc comments as "attaching" to string literal types.

/** @gqlEnum */
type MyEnum = "OK" | "ERROR";

We also support defining enums from a const array using a type query. This is useful when you want one source of truth for both runtime code and type-level checks. For example, you can use the const array at runtime to check whether a user-supplied list covers all enum values:

const ALL_SHOW_STATUSES = ["DRAFT", "SCHEDULED", "PUBLISHED"] as const;

/** @gqlEnum */
type ShowStatus = (typeof ALL_SHOW_STATUSES)[number];

/** @gqlInput */
type ShowStatusFilter = { anyOf: ShowStatus[] };

function applyFilter(filter: ShowStatusFilter) {
// Because ALL_SHOW_STATUSES is a real array, we can compare at runtime
if (filter.anyOf.length === ALL_SHOW_STATUSES.length) {
// No filtering needed — every status was selected
return getAllShows();
}
return getShowsByStatus(filter.anyOf);
}

This form is intentionally strict right now. Grats expects all of the following:

  • ALL_SHOW_STATUSES must be a local top-level const
  • The initializer must be a direct as const array literal
  • The array must be non-empty
  • Every value must be a unique string literal
  • Every value must be a valid GraphQL enum name

Because this is still a type-alias enum form, it has the same tradeoffs as string-literal unions:

  • You cannot add descriptions to enum values
  • You cannot mark enum values as deprecated

Type-alias enums (including this form) are also not supported when tsClientEnums is enabled. In that case, use an exported TypeScript enum declaration instead.