http://learnyousomeerlang.com/dialyzer
But is still optional to compile. The more precise and better the type annotations, the more helpful it is. If it can deduce that some inconsistency or type error occurring it will let user know. If it is not sure, it won't say anything.
Another point is because of isolated process heaps and extra fault tolerance, it is possible to get a high degree of assurance from a system built in Erlang or Elixir even with dynamic typing. And there are certainly many examples of that.
Elixir also follows the Ruby philosophy of hiding as much behind the syntax as possible, whereas Elm tends to be very explicit. So I stand by my point that Elixir is a very different language in practice from Elm.
This is not true. While Elixir may not make things as explicit as Elm (I don't know Elm well enough to assert or refute such a statement), the author of Elixir has stated in various occasions that Elixir prefers explicit to implicit.
For instance, in Elixir, unless one explicitly defines a String.Chars protocol for a data structure, string interpolation of that data structure will not compile. In contrast, pretty much everything can be implicitly interpolated in Ruby.
Another example is function calls. In Elixir, if f is not a named function but a variable bound to an anonymous function, you cannot call it by writing something like f(x). Instead, you must put a dot after f and write f.(x) to state clearly that you are calling an anonymous function.