Posted on elixir forums as well with more details: https://elixirforum.com/t/what-is-wrong-with-my-auto-generated-typespec/54344
Basically I don't get what's wrong with it. I'm auto-generating the definitions like this:
ts = args
|> Enum.map(&{String.to_atom(&1.name), ExOpenAI.type_to_spec(&1.type)})
|> Enum.reduce(fn item, acc -> {:|, [], [item, acc]} end)
Generating 2 types, one hard-coded, one through my generated above:
@type test_1 :: unquote(ts)
@type test_2 :: {:user, String.t()} | {:top_p, float()} | {:temperature, float()}
Then using it in a function @spec definition like usual with [test_1] or [test_2].
Checking with t:
iex(65)> t MyMod.test_1
@type test_1() ::
{:user, String.t()}
| {:top_p, float()}
| {:temperature, float()}
| {:stream, boolean()}
| {:stop, any()}
| {:presence_penalty, float()}
| {:n, integer()}
| {:max_tokens, integer()}
| {:logit_bias, map()}
| {:frequency_penalty, float()}
iex(65)> t MyMod.test_2
@type test_2() ::
{:user, String.t()} | {:top_p, float()} | {:temperature, float()}
So far so good, they look identical to me, with test_1 being longer
However, dialyzer/LSP are not catching the spec violation when using type_1, but are reporting incorrect usage (as they should) with type_2.
Trying to auto-generate a typespec for a longer opts keyword list parameters. Reduce function: ts = args |> Enum.map(&{String.to_atom(&1.name), ExOpenAI.type_to_spec(&1.type)}) |> Enum.reduce(fn item, acc -> {:|, [], [item, acc]} end) Generating 2 types, one hard-coded, one through my generated above: @type test_1 :: unquote(ts) @...