I see optional typing as the opposite of mandatory typing. You don't need to pass a type checker to get a program semantics.
Typed Clojure offers a particular flavour of optional typing: gradual typing. My interpretation of gradual typing is some of your code is rigorously statically typed, some is untyped, and there is some mediator that handles the interface between the two. (Typed Clojure lacks the mediator atm). You need to be explicit about the boundaries between typed/untyped to make the most of the type system.
If you're providing a library, the implementation could be completely untyped, but you might have annotations for your API.
Admittedly I've been exclusively researching Typed Racket style type systems for awhile now, but I'm sceptical that the kind of type system you describe would be effective in finding bugs in your programs. It might find them, but error messages will probably be unpredictable and unreadable, and the type system would not have simple rules to get a namespace type checking like Typed Clojure/Racket does. (eg. assign types to top-levels and fn parameters.)
I'm fairly confident that if you use core.typed, you'll see it's not for everything, but that it can rigorously type check some isolated code, which is often a use case. There are tradeoffs here: the more flexible the type system is, the more complicated the rules are for what type checks, and there will probably be tradeoffs in the accuracy of the static type system.
Also knowing that you've applied a picky, accurate type checker such as core.typed on a large code base is a (valid) good feeling. It will take investment though. In my experience, writing static types for functions is similar to a code review, and probably makes you think about what your code is doing a little more.
Thanks,
Ambrose