Thanks! I tried this myself, but I got stuck, so this will definitely help understanding macros :D
Though, I think I will use this solution, as I will need the `func typeId[T]()` anyway. I am not sure if it is all sound, but it at least seems to work. And while it pretty inelegantly does all the stuff at runtime, it doesn't require registering component types: func getUniqueId(): int = {.cast(noSideEffect).}: var idCounter {.global.} = 0 result = idCounter idCounter += 1 func typeId[T](): int = {.cast(noSideEffect).}: let id {.global.} = getUniqueId() return id type ComponentVectors = seq[ref seq[int8]] func get[T](componentVectors: var ComponentVectors): var seq[T] = static: doAssert (ref seq[int8]).default == nil let id = typeId[T]() if componentVectors.len <= id: componentVectors.setLen(id + 1) if componentVectors[id] == nil: componentVectors[id] = new seq[int8] assert componentVectors[id] != nil cast[ref seq[T]](componentVectors[id])[] func get[T](componentVectors: ComponentVectors): seq[T] = let id = typeId[T]() if componentVectors.len > id and componentVectors[id] != nil: return cast[ref seq[T]](componentVectors[id])[] var c: ComponentVectors c.get[:float]().add(0.5) c.get[:int]().add(1234) c.get[:float]().add(0.6) echo c.get[:float]() echo c.get[:int]() Run