Struct vs. @type t

Convention.

Yes. If you will use just %MyStruct{} then the types specified in t() will not be used. So:

@type t :: %MyStruct{a: integer()}

@spec pass(%MyStruct{}) :: term()
def pass(t), do: t

@spec fail(t()) :: term()
def fail(t), do: t

s = %MyStruct{a: "bar"}

pass(s)
fail(s) # this will cause Dialyzer error

If there is defined t() then you should always use that.

Yes, as shown above.