(assuming the bug here is a description being assigned to a title)
getDescription simply needs to return a Description object while getTitle returns a Title object. Duh.
Only in the final rendering should it get turned into a string and there it should only accept a Title type for doing so.
Okay, I'm kind of joking, but this is seriously the solution if you really want to get down to it - primitive overuse is the problem, so wrap it in a type that makes it explicit. You need cheap and easy types to take full advantage of this sort of thing.
EDIT: And even with those reading code developed in such a way may go overboard at some point. I'm not sure as I haven't really seen it done to the fullest extent possible. Typically even when taking a fairly strong advantage of such a type system, unit tests and stuff are still used, but theoretically you could enforce their parameters entirely in the type system. Of course, that enforcement can also be incorrect, but it does make it clearer in many cases.
I can see your argument in some cases, but if you are accepting input, at some point you'll have to accept a string (or any primitive) and convert it to your custom type.
How does static typing ensure you're mapping the correct JSON input fields to your custom types?
> How does static typing ensure you're mapping the correct JSON input fields to your custom types?
Ideally you push it all the way out. Rather than JSON you use Thrift or similar where the messages are strongly typed.
But if you do use JSON, how much benefit does unit testing your JSON mapping really give you? The mapping in code is just a list of field:field pairs, the test is just the same thing, is there really any value in repeating it twice? I'd sooner rely on careful code review than a test.