I know that my numbers are not totally accurate, but this is the way I got them:
In my main scene I have a label that shows the current memory usage (OS.get_static_memory_usage()). When I let the program run without that array of objects, I get ~27.56 mb of memory (due to sprites, etc.). When I run the program with an array of 100,000 of these objects, I get ~97.61 mb.
That means that the objects take up ~70.05 mb.
So one object is ~705 bytes. And that value is pretty much consistent.
When I do the same steps with a PoolIntArray instead, I get a value of ~4 bytes per element (per integer).
The problem of an dictionary is that it also increases the size of an simple integer, because (as you already mentioned) GDScript is dynamically typed.
But if there is no other way to reduce the size of a class object, I have no problem of using multiple pools of values, there is just more to care about and in the end I would just prefer classes but don't need them necessarily.