Skip to content

Const array enum support#215

Closed
maraisr wants to merge 4 commits intocaptbaritone:mainfrom
maraisr:mr/enum-const-array
Closed

Const array enum support#215
maraisr wants to merge 4 commits intocaptbaritone:mainfrom
maraisr:mr/enum-const-array

Conversation

@maraisr
Copy link
Copy Markdown

@maraisr maraisr commented Mar 6, 2026

Thanks again so much for this library, it's literally a dream.

I ran up against something recently, in wanting to have runtime enum values as well. I did not really want to use TypeScripts enum mechanism (not a fan). Though maybe that is the canonical way to do that, in which case happy to close this pr.

But yeah, I wanted to do something like this:

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);
}

You know, have the ability to see if the user-provided set includes all enum variants. I did not like the fact that I needed to define those twice:

/** @gqlEnum */
type ShowStatus = "DRAFT" | "SCHEDULED" | "PUBLISHED";
const ALL_SHOW_STATUSES: readonly ShowStatus[] = ["DRAFT", "SCHEDULED", "PUBLISHED"];

Like yeah, I do still have type-safety so if I add an item to one, that it exists in the other. But my OG DRY self wanted only one place to define that.

So here we are, a PR that adds that support. What do you think @captbaritone? Is this a direction/feature/inevitably code you'd likely need to maintain, something you're interested in?

I'll be honest, I've never worked in this codebase before. And definitely didn't quite have the brain space to fully understand it (though would like to help moving forward). So asked Amp to to help me: https://ampcode.com/threads/T-019cc14e-74ed-75ef-8fbe-339f5d582962

@netlify
Copy link
Copy Markdown

netlify bot commented Mar 6, 2026

Deploy Preview for grats ready!

Name Link
🔨 Latest commit 9ea85a7
🔍 Latest deploy log https://app.netlify.com/projects/grats/deploys/69aa6213be1fd9000896c0d2
😎 Deploy Preview https://deploy-preview-215--grats.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

captbaritone added a commit that referenced this pull request Apr 1, 2026
Add support for two new patterns for defining GraphQL enums with
runtime-accessible values:

- Const array: `(typeof VALUES)[number]`
- Const object: `(typeof OBJ)[keyof typeof OBJ]`

The const declaration must be the immediately preceding statement before
the @gqlEnum type alias, ensuring it's clear which declarations
contribute to the GraphQL schema. This avoids introducing name
resolution into the Extractor.

Const objects support descriptions and @deprecated on properties. Const
arrays share the same limitation as union-of-literal enums (no per-value
metadata), since TypeScript doesn't attach JSDoc to array elements.

Also fixes TypeContext.findSymbolDeclaration to prefer declarations
registered in the GraphQL schema when a symbol has multiple declarations
(needed for the `const X` + `type X` same-name pattern).

Closes #205. Supersedes #215.
captbaritone added a commit that referenced this pull request Apr 1, 2026
* Support deriving @gqlEnum from const arrays and const objects

Add support for two new patterns for defining GraphQL enums with
runtime-accessible values:

- Const array: `(typeof VALUES)[number]`
- Const object: `(typeof OBJ)[keyof typeof OBJ]`

The const declaration must be the immediately preceding statement before
the @gqlEnum type alias, ensuring it's clear which declarations
contribute to the GraphQL schema. This avoids introducing name
resolution into the Extractor.

Const objects support descriptions and @deprecated on properties. Const
arrays share the same limitation as union-of-literal enums (no per-value
metadata), since TypeScript doesn't attach JSDoc to array elements.

Also fixes TypeContext.findSymbolDeclaration to prefer declarations
registered in the GraphQL schema when a symbol has multiple declarations
(needed for the `const X` + `type X` same-name pattern).

Closes #205. Supersedes #215.

* Update llm-docs for const enum support

* Use GratsCode snippets for const enum docs examples

Replace inline code blocks with compiled GratsCode snippets so the
examples are validated by the Grats compiler. Also add a comment to the
array-with-description test fixture explaining that descriptions on
array elements are silently ignored.
@captbaritone
Copy link
Copy Markdown
Owner

Thanks for the PR! I took ideas from here and from #205 and implemented a somewhat different approach in #225.

You can install grats@main to try it out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants