One thing to note is that, as things currently stand, objects may silently allow variables which aren’t defined, which is intended, but not always what people expect.
So another option, if you want to defend against typos etc, is to use map(any) or list(map(any)) or whatever, and do custom validation in the variables – for reasons described in that issue, custom validation doesn’t work as you’d expect with an object definition in place. That said, the more complex / nested the object, the trickier that validation is to write and maintain.