Logo Xantham

Code Keys — tagged dispatch over TypeKey

A raw TypeKey is just an opaque address into the type or export map. It does not, by itself, tell a generator whether the construct it points at is a union, a class, a function export, or a primitive.

The CodeKey family solves this by tagging a TypeKey with the kind of construct it identifies, so generators can pattern match without re-walking the underlying TsType / TsExportDeclaration.

The three layers

CodeKey
 ├── Export of ExportCodeKey  ── Variable | Interface | TypeAlias | Class | Enum | Module | Function
 └── Type   of TypeCodeKey    ── GlobalThis | Conditional | Primitive | Union | …

How to obtain one

The recommended path is XanthamTree.Codify:

let kind = tree.Codify someKey
match kind with
| CodeKey.Export (ExportCodeKey.Class classKey)     -> ...
| CodeKey.Export (ExportCodeKey.Function funcKey)   -> ...
| CodeKey.Type   (TypeCodeKey.Union unionKey)       -> ...
| CodeKey.Type    TypeCodeKey.GlobalThis            -> ...
| _ -> ...

Codify resolves the key against both maps in a single pass: if it finds an export it categorises against ExportCodeKey; otherwise it categorises the structural type. TsType.Interface, TsType.Class, and TsType.Enum are folded into the Export branch even when the key is reached via the structural map.

Why a separate type

Dispatch tables

A common pattern is to build a frozen dictionary of generators keyed by case constructor:

let renderType =
    function
    | TypeCodeKey.Union k        -> renderUnion k
    | TypeCodeKey.Intersection k -> renderIntersection k
    | TypeCodeKey.Tuple k        -> renderTuple k
    | TypeCodeKey.Primitive k    -> renderPrimitive k
    // …

Because every TypeCodeKey / ExportCodeKey case is a single TypeKey payload, the matched key flows straight through into the renderer.

Type something to start searching.