Question: I'm learning Elixir, and the tool 'dialyzer' lets you do static analysis - annotate the function definition with the type specification of the parameters it expects and the output it returns. It's completely optional, but if it were to be used to the full extent possible, how does it match up to good 'ol static typing?

Answer: 
My impression was that dialyzer is not as exact as static typing, meaning that it sometimes doesn't report an error, although it should.

On the plus side, if a dialyzer complains, it's almost always my fault. More often than not, errors are usually due to incorrect typespec.

So, while I don't think dialyzer is as good tool as static typing, it still helps. In particular, I find typespecs very useful, since they can serve as a documentation. Recently I've switched job, and the project I joined is a complex Erlang project. Owing to typespecs it was easy to find my way around the codebase.

So my advice is to use typespecs in larger projects. We write them only for exported (public) functions and records, and it's a big help, without taking up too much time. I usually first make the code work, and when I'm happy with it, add specs, and run dialyzer to verify all is fine.
For one thing static typing is built into the compilation phase--sort of impossible to miss. Static analysis on the other hand is something that a developer has to run voluntarily.

Likewise, one doesn't have to annotate anything in Elixir; it's entirely down to programmer discretion. In statically typed languages it's impossible to avoid.

I would say your question is sort of broad and therefore hard to answer with any rigor. You might want to put this over on Programmers.Stackechange.