Skip to content

Typing in Elixir

Elixir is dynamically typed, but not “untyped.” Values have types at runtime, and the language gives you several ways to document, constrain, dispatch on, and check those types.

Runtime values are typed. Variables are not statically typed. Function contracts are usually expressed through pattern matching, guards, structs, typespecs, behaviours, and protocols.

Elixir’s official site describes it as a “dynamic, functional language” running on the Erlang VM (the BEAM).

Elixir has several built-in types that you can use to define the type of a value.

:ok # atom
42 # integer
3.14 # float
"hello" # binary / string
'hello' # charlist
[1, 2, 3] # list
{1, 2} # tuple
%{name: "Owais"} # map
fn x -> x + 1 end # function
pid # process id

A struct is a map with a named shape. Under the hood, they have a __struct__ field that stores the struct’s name.

You model data with tagged tuples, maps, and structs, then branch by shape, as Elixir uses shape-based pattern matching.

Guards are expressions that are evaluated at runtime to determine if a pattern matches. They can be used in pattern matching to constrain the values that can be matched.

Common helpers:

is_atom/1
is_binary/1
is_boolean/1
is_float/1
is_function/1
is_integer/1
is_list/1
is_map/1
is_number/1
is_tuple/1

Typespecs are annotations1 used to specify the type of a function’s arguments and return value. They’re not enforced by the compiler, but for documentation and static analysis tools like Dialyzer.

Behaviours are interface-like contracts. They define callback contracts that modules can implement.

Protocols provide type-based polymorphism, by defining behaviors that can vary by data type.

This is a part of an ongoing effort2 to introduce type-checking to the Elixir compiler.

  1. Gradual typing - You can keep writing normal dynamic Elixir. The type system is introduced incrementally and does not require rewriting the ecosystem.
  2. Set-theoretic typing - A type is treated as a set of possible values. Type operations work like set operations: union, intersection, and difference/negation.
  1. Typespecs Reference — Elixir v1.19.0-Rc.0. https://elixir.hexdocs.pm/1.19.0-rc.0/typespecs.html. Accessed 31 May 2026.

  2. Gradual Set-Theoretic Types — Elixir v1.19.5. https://elixir.hexdocs.pm/gradual-set-theoretic-types.html. Accessed 31 May 2026.