Open mattste opened 1 year ago
Unfortunately this is not supported as far as I know, for now the workaround is indeed to use
@role_values [:admin, :billing, :content_editor, :content_viewer]
@type role :: :admin | :billing | :content_editor | :content_viewer
defmodule OrganizationMembership do
typed_schema "organizations_memberships" do
field(:role, Ecto.Enum, values: @role_values) :: role()
end
end
In my project I do use a macro to simplify this:
defmodule OrganizationMembership do
import UnionType
@role_values [:admin, :billing, :content_editor, :content_viewer]
union_type(role :: @role_values)
typed_schema "organizations_memberships" do
field(:role, Ecto.Enum, values: @role_values) :: role()
end
end
where
defmodule UnionType do
defmacro union_type({:"::", _, [{name, _, _}, data]}) do
quote bind_quoted: [data: data, name: name] do
@type unquote(name)() :: unquote(UnionType.union_type_ast(data))
end
end
def union_type_ast([item]), do: item
def union_type_ast([head | tail]), do: {:|, [], [head, union_type_ast(tail)]}
end
That could be a nice feature to have. Not sure the ergonomics, but it could be interesting to automatically generate types for Ecto.Enum types. That would need to be opt-in though, as it has a possibility of conflicting with other types or need to be "prefixed", which might not yield the nicest type names.
I'm looking for a way to access an individual field's type.
Given the following schema:
I was hoping to find a way to do something like
OrganizationMembership.role()
so typespecs in other modules can use it. My current workaround is to manually define arole
type and have the field use that. Perhaps there is already a way but it's not public surface area?