While `StoreKind` can be any of `StoreInt|StoreFloat|StoreString`, once it is instantiated, it will stay that one. Instead you have two choices:
1\. derive from a common `Store` object: type Store = ref object of RootObj dep: seq[Store] req: seq[Store] StoreInt = ref object of Store val: int StoreFloat = ref object of Store val: float StoreString = ref object of Store val: string 2\. use object variants: type StoreKind = enum StoreInt, StoreFloat, StoreString Store = ref object of RootObj case kind: StoreKind of StoreInt: intVal: int of StoreFloat: floatVal: float of StoreString: strVal: string dep: seq[Store] req: seq[Store] var a = Store(kind: StoreInt, intVal : 5, dep: @[], req: @[])