Enums and scalars#

Meta: split this 50/50 — both feel obvious on the page but trip people up in real code (enum literal vs. string, scalar coercion timing).

Enums#

Declaration#

enum Color { RED GREEN BLUE }

Values#

As function arguments#

usersByStatus(status: Status.ACTIVE)

In case#

case (c) {
  Color.RED => "stop"
  Color.GREEN => "go"
}

From strings (::)#

Custom scalars#

Declaration#

scalar Email
scalar JSON

Coercion#

Treating scalars as opaque#

Meta: the :: rule is the durable contract — literals are a convenience, non-literal values always go through an explicit cast.

Built-in scalars#

Meta: scalar fields are invariant across interface implementation — id: String! does not satisfy id: ID!. Cross-ref the variance rules in Interfaces and unions.

See also: enum values and custom scalars declared in an imported schema are reached through the module name (see Modules and imports); GraphQL representations are covered in GraphQL interop.