I go a little back and forth on this with my experience in F#, which relies heavily on inferred types. You can write a lot of F# before you need to add type annotations, but eventually, things become a spiderweb. The key issue is when you make a 'small' change to some method/value, the changes ripple through the program creating confusing errors sometimes where the compiler is trying to knit things together.
After a while, I found myself adding back types in a decent number of places to "anchor" the type inference, indicating that a certain type/signature is fixed and a change should be carefully considered.
I still don't know how folks deal with these kinds of changes in weakly typed languages without always allowing bugs to pour into their code over time. But I do love the "move fast" and low boiler-plate aspects of "typeless" coding.
After a while, I found myself adding back types in a decent number of places to "anchor" the type inference, indicating that a certain type/signature is fixed and a change should be carefully considered.
I still don't know how folks deal with these kinds of changes in weakly typed languages without always allowing bugs to pour into their code over time. But I do love the "move fast" and low boiler-plate aspects of "typeless" coding.