How to typespec function that adds a key to a map

I have a function that takes a map with a couple of keys (17) and returns a map with additional 18th key.

def foo(map), do: Map.put(map, :another_key, value)

The type of input is:

@type t() :: %{
  :key1 => String.t(),
  :key2 => String.t(),
  optional(:key3) => integer(),
  ...
}

Is there a way to make a spec for the foo function that doesn’t require repeating the entire typespec for output map? Something like t() but with key18 => String.t()

As far as I am aware, there is not. You are able to do some trickery with quote/unquote in typespecs to reduce repetition, but the resulting code is far from pretty.

See Specifying map or struct extension using typespecs for a recent discussion about essentially the same situation.

1 Like

Thank you! I missed that topic while searching :slight_smile: Hmm, I am not sure how to make this answer work with optional. It works with key: type where key is required. But how do I make it work with optional?