What's the difference between a struct and a type in a @spec?

What’s the difference between a struct and a type in a @spec?

  @spec my_func(%MyStruct{}) :: %MyStruct{}
  def my_func(var), do: # implementation
    
  @spec my_func(MyStruct.t) :: MyStruct.t
  def my_func(var), do: # implementation

Assuming that the MyStruct exported a type and looked something like this:

defmodule MyStruct do
    @enforce_keys [:x, :y, :z]
    defstruct x: %{}, y: %{}, z: %{}
    @type t :: %__MODULE__{x: map, y: map, z: map}
end

Are there times when one is preferable over the other? I ran into some cases where I would get an error about being unable to expand the struct.

Thanks!

3 Likes

%MyStruct{} in a type is equivalent with %{__struct__: MyStruct, x: any(), y: any(), z: any()}.

Only the MyStruct.t/0 carries additional information about individual fields types.

6 Likes