Type systems can be nominal or structural, they might force an option type, and they might even encode side effects (IO or exceptions).
I think the biggest single improvement (where compiles≈correct) is exhaustiveness checking. This produces thoroughness and often robustness.
Related Posts
Really cute approach to reporting type errors: when there's a type error, show an example of a runtime error that the type check has prevented!
Data-Driven Techniques for Type Error Diagnosis https://escholarship.org/uc/item/59s4h4pv
Playing with optional type signatures in Python, I realise that the return type is the most important to me.
I'd much rather have a function with only a return type instead of a function with only parameter types. It's often quick to add too.
@tristanC That's an option! There's often cases where you know what the user wanted though, so you can provide a sensible AST that the toolchain can handle.
For example, a malformed string literal can still be parsed a string so type checking etc can be helpful.