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.