I think your last sentence is completely wrong.
A good enough type system you will be able to express abstractions so powerful that it turns the "straitjacket" into a suit of power armour. Instead of restricting the programmer, a good type system like Haskell's allows you to express your intent and program with certainty that many errors (like forgetting to handle an exception) are simply impossible.
There are also some things that are very cumbersome to write in dynamic languages. For example in Python it is a complete pain to write code that is datastructure-agnostic. A while ago I was working on some code where I had nested dictionaries with lists in them that contained single values and more lists/dictionaries, and found myself wanting to transform all the lists inside the thing in a certain way. In Haskell, this would've been trivial using the fmap function (type f a -> (a -> b) -> f b) which is a generalized map that works for any functor... The python solution ended up being a fragile hack of manual type checks and dispatch, since there is no uniform interface that all the data structures can implement.
I feel like dynamic programming languages are a good solution for prototyping and small programs/modules (eg. UI and scripting systems), but as systems grow larger, the amount of things you have to worry about grows exponentially, and a type system (+ immutability) helps keep it all together by minimizing the amount of parts that a change can affect.