> Most of the data I deal with are strings with their own validation and formatting rules that are complicated and at the same time usually need to be permissive

this is exactly where a good type system helps: you have an unvalidated string and a validated string which you make incompatible at the type level, thus eliminating a whole class of possible mistakes. same with object ids, etc.

don't need haskell for this, either: https://brightinventions.pl/blog/branding-flavoring/

That's neat, I was about to ask which languages support that since the vast majority don't. I didn't know that you can do that in Typescript.

Any language with an type system really...

Even OOP : if you have a string class, you can have a String_Formated_For_API subtype.

Just extends String, and add some checking.

But now the type checker "knows" it can print() a String_Formated_For_API just fine but not call_API(string).