   specification parameter does not exist, this function
   will raise. Returns `nil` if the application is not loaded.
   """
-  @spec spec(app, key) :: value | nil
+  @spec spec(app, application_key) :: value | nil
   def spec(app, key) when is_atom(app) and key in @application_keys do
     case :application.get_key(app, key) do
       {:ok, value} -> value

      defoverridable Application
    end
  end

  @type app :: atom
  @type key :: atom
  @type value :: term
  @type state :: term
  @type start_type :: :normal | {:takeover, node} | {:failover, node}
  @type restart_type :: :permanent | :transient | :temporary

  @application_keys [
    :description,

    :start_phases
  ]

  application_key_specs = Enum.reduce(@application_keys, &{:|, [], [&1, &2]})

  @type app :: atom
  @type key :: atom
  @type application_key :: unquote(application_key_specs)
  @type value :: term
  @type state :: term
  @type start_type :: :normal | {:takeover, node} | {:failover, node}
  @type restart_type :: :permanent | :transient | :temporary

  @doc """
  Returns the spec for `app`.

