Static typing obviates most runtime type checking, which your module boundaries need to be doing (and exercising in tests). Libraries like runtypes deal with the last mile of it by generating runtime type guards that also project back into the static type system. This removes the need for entire classes of tests, as well as many of those handling intra-module transforms. It's telling that the people doing some of the best work in, say, Ruby are in on both tooling like Sorbet and libraries like dry-types/dry-struct -- because the benefits are significant in terms of minimizing engineering risk.
Static typing is also standardized and machine-readable documentation. This can't be understated. Human-written documentation rots with changes. The guarantees at module level from your static types does not.
Particularly when gradually introduced, these are significant force multipliers. If you want to take on the additional risk for your toy projects, more power to you (I sometimes write Ruby when doing something that doesn't matter) but I certainly find those benefits significantly more than "marginal" if anyone else ever has to deal with my code--including future-me.
I've heard this argument many times but it's misleading. Well written functional tests will be able to identify type mismatches implicitly. For example if you add 10 + "1", you will get "101" - The test will fail. You don't need to check if the result is a string, you just need the assertion to expect the number 11. Tests will catch type mismatches implicitly. In practice, this applies to pretty much every kind of type mismatch. Type mismatches break functionality; so if the functionality is well tested, then type mismatches will be caught implicitly.
Do you have any large typescript projects?