How is it hidden? Can't the inquiring mind simply examine the codebase to see it's a struct? And if they choose not to, isn't it on them if it turns out to be something other than what they assumed it was without looking?
There is a point, perhaps a little specious, that you put a module's data structures behind a typedef so the interface doesn't change if it changes from a simple data type to a struct. Probably doesn't happen too often.
The perfect C object-oriented-style interface is FILE* from stdio.h. A FILE is a structure full of operating-system-specific file information but you never have to see it or worry about what's in it, you just use the functions.
you could never do this in C. If it is a "value type" i.e. a non-pointer, then you cannot change the size of the value, without changing the ABI and the function decl.