bamorim / typed_ecto_schema

A library to define Ecto schemas with typespecs without all the boilerplate code.
https://hexdocs.pm/typed_ecto_schema
Apache License 2.0
268 stars 18 forks source link

Differentiate type inference for fields and assocs/embeds #21

Open bamorim opened 2 years ago

bamorim commented 2 years ago

The compile-time problem and the current fix led me to think our current type inference is not ideal.

We treat assocs (has_many, has_one, belongs_to, many_to_many) and embeds (embeds_one, embeds_many) the same way we treat field.

The problem is that some assumptions don't translate very well. For example, while for assocs it always have a schema module being defined, fields can be primitives, custom types, composite types or parametrized types.

The problem with custom types (parametrized or not) is that the type name is a module and our current inference then defaults to mod.t() as the type.

This is a good one for assocs since, I assume, most projects using typed_ecto_schema would be using typed_schema/typed_embedded_schema for all schemas, which would always generate a t() type.

That however, is not good for ecto types because it won't be using our library to implement Ecto.Type behaviour.

This is why we have weird edge cases for things like the Ecto.Enum.

My idea going forward would be to split the type inference of assocs/embeds and fields completely.

With that I'd actually re-introduce compile-time dependency for field, so we can check a custom method like beam_type/1 that could be added to Ecto.Types to generate the beam type. We could even have a way to config modules defining these types for externally defined ecto.types, which could even be how we define the type for Ecto.Enum.

Also, if we couldn't infer, I think the default should be any() instead of mod.t()

Then, for assocs, we could leave the way it currently is (defaulting to mod.t()).

Thoughts on that?