diff options
author | Nathan Long <him@nathanmlong.com> | 2023-03-22 09:48:49 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-22 14:48:49 +0100 |
commit | e2a207a4559527c43165b47ff8e7c981ae039112 (patch) | |
tree | 1e78aed18ac3729c47d1b69389ee0b3e06530ec1 | |
parent | bb1c89536d79ecf56ad4c9ebb6a3fad8dadbb203 (diff) | |
download | elixir-e2a207a4559527c43165b47ff8e7c981ae039112.tar.gz |
Examples of composing a keyword list type (#12482)
Examples by Myron Marston and Michał Muskała in
https://elixirforum.com/t/typespecs-best-way-to-spec-keyword-lists/2991
-rw-r--r-- | lib/elixir/pages/typespecs.md | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/elixir/pages/typespecs.md b/lib/elixir/pages/typespecs.md index 7eea7e0fc..74fa2fd0a 100644 --- a/lib/elixir/pages/typespecs.md +++ b/lib/elixir/pages/typespecs.md @@ -172,6 +172,32 @@ it is common to end a map type with `optional(any) => any`. Note that the syntactic representation of `map()` is `%{optional(any) => any}`, not `%{}`. The notation `%{}` specifies the singleton type for the empty map. +### Keyword Lists + +Beyond `keyword()` and `keyword(t)`, it can be helpful to compose a spec for an expected keyword list. +For example: + + +```elixir +@type option :: {:name, String.t} | {:max, pos_integer} | {:min, pos_integer} +@type options :: [option()] +``` + +This makes it clear that only these options are allowed, none are required, and order does not matter. + +It also allows composition with existing types. +For example: + +```elixir +type option :: {:my_option, String.t()} | GenServer.option() + +@spec start_link([option()]) :: GenServer.on_start() +def start_link(opts) do + {my_opts, gen_server_opts} = Keyword.split(opts, [:my_option]) + GenServer.start_link(__MODULE__, my_opts, gen_server_opts) +end +``` + ### User-defined types The `@type`, `@typep`, and `@opaque` module attributes can be used to define new types: |