grats icon indicating copy to clipboard operation
grats copied to clipboard

Additional syntax for reusing variable statements

Open cometkim opened this issue 3 months ago • 0 comments

Hi. I'm experimenting grats on my project, which is using erasableSyntaxOnly flag for Node.js' built-in TypeScript support.

Currently, grats enum can only be used with TS enum and type aliases.

Many TS projects are using plain JS dict with as const to replace TS enum. Or even with Zod

enum MyEnum = {
  Valid = "VALID",
  Invalid = "INVALID",
}

// can be replaced by

const MyEnum = {
  Valid: "VALID",
  Invalid: "INVALID",
} as const;

type MyEnum = typeof MyEnum[keyof typeof MyEnum];
// or with utility type
type MyEnum = Enum<typeof MyEnum>;

So, I'm trying to add support for @gqlEnum with object literals, but there is an issue with type references.

/** @gqlType */
class SomeType {
  /** @gqlField */
  hello: typeof MyEnum[keyof typeof MyEnum];
}

/** @gqlEnum */
const MyEnum = {
  VALID: "VALID",
  INVALID: "INVALID",
} as const;

hello: typeof MyEnum[keyof typeof MyEnum] is not statically referenced anymore. Perhaps grats can provide the Enum utility for it, but it may conflict with user-defined utilities.

My idea is just allowing to override field type by @gqlField directive, e.g.

/** @gqlType */
class SomeType {
  // when typename is preserved
  /** @gqlField {@link MyEnum} */
  hello: typeof MyEnum[keyof typeof MyEnum];

  // or just its name
  /** @gqlField {MyEnum} */
  hello: typeof MyEnum[keyof typeof MyEnum];
}

Syntax is similar to TS' @param (@link for LSP go-to-def support)

Then it unlocks the use cases of grats in real-world TypeScript projects that rely on many type-level utilities.

Thoughts?

cometkim avatar Nov 11 '25 10:11 cometkim