Typespec question

Hi, all.

I have read several elixir books and the only Ecto book, and still confused on Typespecs. I googled a few articles on typespecs including official Typespect document of Elixir site and questions in elixir forum here, but not clear at all.
For example,

defmodule Friends.Person do
  use Ecto.Schema

  schema "people" do
    field(:first_name, :string)
    field(:last_name, :string)
    field(:age, :integer)
  end

  @spec changeset(
          {map, map} | %{:__struct__ => atom | %{__changeset__: map}, optional(atom) => any},
          :invalid | %{optional(:__struct__) => none, optional(atom | binary) => any}
        ) :: Ecto.Changeset.t()
  def changeset(person, params \\ %{}) do
    person
    |> Ecto.Changeset.cast(params, [:first_name, :last_name, :age])
    |> Ecto.Changeset.validate_required([:first_name, :last_name])
  end
end

I hope someone explain the typespec of the changeset function above.
I guess,

  1. The paremeters of the changeset function can be one of the three:
(1) {map, map}, 
(2) %{:__struct__ => atom | %{__changeset__: map}, optional(atom) => any}, :invalid , 
(3) %{optional(:__struct__) => none, optional(atom | binary) => any}
  1. In the first case(1) of {map, map}, The type of the first parameter person is a struct, and that of the second is a map. What is the meaning of {map, map} tuple? That is to say, why {} is necessary here?
  2. In the second case(2), the changeset function needs only two parameters, then why the third parameter, :invalid atom, is there? What is the meaning of __strunct__ in :__struct__ => atom? What is the meaning of __changeset__ in %{__changeset__: map}? What is the meaning of `optional(atom) => any’ here?
  3. What is the meaning of the third case(3)? %{optional(:__struct__) => none, optional(atom | binary) => any}

It’s quite a verbose question, but it surely will help many novices in the future who visit this forum or googling similar questions.

Always thank you all.