First of all, types specified with the @type
directive are public by default (as opposed to types defined with @typep
). This means that even if a module has no specs in it, defining a type allows other developers to use that type when writing their functions:
@doc "Computes the length of a URI."
@spec foo(URI.t) :: non_neg_integer
def foo(uri), do: # ...
__MODULE__
is a special form that expands to the current module name as an atom (see the docs for it), so this:
defmodule MyModule do
@type t :: %__MODULE__{}
end
will define a MyModule.t
type. The most common use of the t
type is for representing structs and protocols (e.g., Enum.t
). This pattern is extremely common:
defmodule User do
defstruct [:name, :email]
@type t :: %__MODULE__{name: String.t, email: String.t}
end