Skip to content

Additional syntax for reusing variable statements #205

@cometkim

Description

@cometkim

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions