This one had me second-guessing myself, but I’m fairly certain this is an error in both the book’s code sample and the provided source:
@spec parse_response(Weather.t()) :: {:ok, list(Weather.t())} | {:error, atom()}
This function is supposed to take the Jason-transformed response from the API, which should just be a raw map, not the Weather struct. That’s how it is used in the following test, and in the project source.
Solution
The spec should be something like:
@spec parse_response(map()) :: {:ok, list(Weather.t())} | {:error, atom()}
Or something similar, perhaps with a more restrictive map() type that more closely matches the shape of the expected API response.