Dialyzer Warning: Type specification is a subtype of the success typing

This code:

defmodule Vector do
  use TypedStruct

  typedstruct do
    field :x, integer(), enforce: true
    field :y, integer(), enforce: true
  end

  @spec add(Vector.t(), Vector.t()) :: Vector.t()
  def add(%Vector{x: x1, y: y1}, %Vector{x: x2, y: y2}), do: %Vector{x: x1 + x2, y: y1 + y2}
end

Gives this warning on the spec:

Type specification is a subtype of the success typing.
Function:
Vector.add/2
Type specification:
@spec add(t(), t()) :: t()
Success typing:
@spec add(%Vector{:x => number(), :y => number(), _ => _}, %Vector{
  :x => number(),
  :y => number(),
  _ => _
}) :: %Vector{:x => number(), :y => number()}

I’ve set these warnings in elixirls: ["underspecs", "unmatched_returns", "error_handling", "specdiffs"]

Does anyone have an idea what’s wrong or how to fix this?

Remove underspecs.

+/2 applies for any kind of number not only integers, so dialyzer considers your spec as I rely restrictive and asks you to make it wider.

It doesn’t consider that this would break your expectations and invariants elsewhere.

That’s why over-/underspecs are rarely used.

So if I would change my spec to number instead of integer it should also work?

I’ve added underspec because I think it caught something else, but I’m not sure anymore. Going to play a bit more with it.

I’ve been playing with this a bit, and it looks like underspecs is not the culprit but rather specsdiff. When I only have underspecsthe error above is gone.
With only specsdiff I get the error.

Changing integer() to number() has no effect