So the other piece mentioned in the CustomStruct docs, is that you probably want to define a StructTypes.lowertype method, so deserialization gives you something better when deserialization; something like:
StructTypes.lowertype(::Type{Foo2}) = NamedTuple{(:id, :vals), Tuple{Int, Vector{Any}}}
then you’ll need a constructor with a signature like:
function Foo2(id::Int, vals::Vector)
# convert vals from Vector{Any} to Dict
end