But the other context in which we select and choose and construct data types is because a language insists upon it. Here our choices are not based on how to best represent the world, but by how to package our metaphor into a pre-existing schema. The very first time we compile our code, we have been forced by the compiler to crystallize our code based on an early guess.
When a flat roofed building uses scuppers to provide emergency overflow drainage, it is good if water passing through them makes a mess of the plantings below and perhaps stains the facade. It indicates that the primary drains are clogged before the roof collapses. Likewise, runtime type errors might be preferable to zeros silently inserted into a database.
Static and dynamic typing each catch some types of errors at runtime at the expense of masking other types of errors at runtime.
I think types make us write out the why next to the what. That why might be a domain model justification, or something much more trivial. It's also completely possible to encode an untyped regime in a type system. You're always crystallizing your design, you just can either provide good information to understand its failings and be more prepared to fix them. Or not and chase logic errors throughout an undocumented, dynamic system.