I’m trying to write a @spec
for this function that was made by mix phx.gen.auth
:
# lib/my_app/identity/user_token.ex
@spec build_session_token(MyApp.Identity.User.t()) :: {binary(), t()}
def build_session_token(user) do
token = :crypto.strong_rand_bytes(@rand_size)
{token, %UserToken{token: token, context: "session", user_id: user.id}}
end
Unfortunately, I’m getting this error from Dialyxir:
Invalid type specification for function 'Elixir.MyApp.Identity.UserToken':build_session_token/1.
The success typing is 'Elixir.MyApp.Identity.UserToken':build_session_token(atom() | #{'id':=_, _=>_}) -> {binary(),#{'__meta__':=#{'__struct__':='Elixir.Ecto.Schema.Metadata', 'context':='nil', 'prefix':='nil', 'schema':='Elixir.MyApp.Identity.UserToken', 'source':=<<_:96>>, 'state':='built'}, '__struct__':='Elixir.MyApp.Identity.UserToken', 'context':=<<_:56>>, 'id':='nil', 'inserted_at':='nil', 'sent_to':='nil', 'token':=binary(), 'user':=#{'__cardinality__':='one', '__field__':='user', '__owner__':='Elixir.MyApp.Identity.UserToken', '__struct__':='Elixir.Ecto.Association.NotLoaded'}, 'user_id':=_}}
But the spec is 'Elixir.MyApp.Identity.UserToken':build_session_token('Elixir.MyApp.Identity.User':t()) -> {binary(),t()}
The return types do not overlap
I think it looks correct, so I’m confused why I’m getting this error. What should I do to fix this?
EDIT:
# lib/my_app/identity/user_token.ex
defmodule MyApp.Identity.UserToken do
@type t :: %__MODULE__{
__meta__: Ecto.Schema.Metadata.t(),
id: integer() | nil,
token: binary(),
context: String.t(),
sent_to: String.t(),
user_id: integer(),
inserted_at: NaiveDateTime.t() | nil
}
schema "users_tokens" do
# ...
end
end
# lib/my_app/identity/user.ex
defmodule MyApp.Identity.User do
@type t :: %__MODULE__{
__meta__: Ecto.Schema.Metadata.t(),
id: integer() | nil,
email: String.t() | nil,
password: String.t() | nil,
hashed_password: String.t() | nil,
confirmed_at: NaiveDateTime.t() | nil,
inserted_at: NaiveDateTime.t() | nil,
updated_at: NaiveDateTime.t() | nil
}
schema "users" do
# ...
end
end