Types are stored in the doc chunks if you happen to generate them for your modules, for example:
> ht(typechecker).
typechecker
These types are documented in this module:
-type env() :: #env{}.
-type typed_record_field() ::
{typed_record_field, record_field(), type()}.
-type record_field_type() :: gradualizer_type:af_record_field_type().
-type record_field() :: gradualizer_type:af_record_field(expr()).
-type af_field_name() :: gradualizer_type:af_field_name().
-type forms() :: [form()].
...
Their structure is available via the shell_docs
/ EEP-48 machinery - in the signature
field of the metadata:
15> shell_docs:get_type_doc(typechecker, typed_record_field, 0).
[{{type,typed_record_field,0},
[{file,"typechecker.erl"},{location,112}],
[<<"typed_record_field/0">>],
[{p,[],
[<<"There is no documentation for ">>,
<<"typed_record_field/0">>]}],
#{signature =>
[{attribute,112,type,
{typed_record_field,{type,112,tuple,
[{atom,112,typed_record_field},
{user_type,112,record_field,[]},
{user_type,112,type,[]}]},
[]}}]}}]
However, sometimes it’s a rabbit hole:
16> shell_docs:get_type_doc(typechecker, record_field, 0).
[{{type,record_field,0},
[{file,"typechecker.erl"},{location,110}],
[<<"record_field/0">>],
[{p,[],
[<<"There is no documentation for ">>,
<<"record_field/0">>]}],
#{signature =>
[{attribute,110,type,
{record_field,{remote_type,110,
[{atom,110,gradualizer_type},
{atom,110,af_record_field},
[{user_type,110,expr,[]}]]},
[]}}]}}]
17> shell_docs:get_type_doc(typechecker, expr, 0).
[{{type,expr,0},
[{file,"typechecker.erl"},{location,75}],
[<<"expr/0">>],
[{p,[],[<<"There is no documentation for ">>,<<"expr/0">>]}],
#{signature =>
[{attribute,75,type,
{expr,{remote_type,75,
[{atom,75,gradualizer_type},{atom,75,abstract_expr},[]]},
[]}}]}}]
18>
18> shell_docs:get_type_doc(gradualizer_type, abstract_expr, 0).
[{{type,abstract_expr,0},
[{file,"gradualizer_type.erl"},{location,48}],
[<<"abstract_expr/0">>],
[{p,[],
[<<"There is no documentation for ">>,
<<"abstract_expr/0">>]}],
#{signature =>
[{attribute,48,type,
{abstract_expr,{type,48,union,
[{user_type,48,af_literal,[]},
{user_type,49,af_match,[{user_type,49,abstract_expr,[]}]},
{user_type,50,af_variable,[]},
{user_type,51,af_tuple,[{user_type,51,...}]},
{user_type,52,af_nil,[]},
{user_type,53,af_cons,[{...}]},
{user_type,54,af_bin,[...]},
{user_type,55,af_binary_op,...},
{user_type,56,...},
{user_type,...},
{...}|...]},
[]}}]}}]