Yes, Stefan_Salewski is right:
type
NodeKind = enum # the different node types
nkInt, # a leaf with an integer value
nkFloat # a leaf with a float value
# Version 1 with object variant
Node = ref NodeObj
NodeObj = object
case kind: NodeKind # the ``kind`` field is the discriminator
of nkInt: intVal: int
of nkFloat: floatVal: float
# Version 2 with conditional fields
Node2[NK] = ref NodeObj2[NK]
NodeObj2[NK: static[NodeKind]] = object
when NK == nkInt:
intVal: int
elif NK == nkFloat:
floatVal: float
# Compiles fine
let a = @[NodeObj(kind: nkInt), NodeObj(kind: nkFloat)]
# Doesn't compile
let b = @[NodeObj2[nkInt](), NodeObj2[nkFloat]()]