I do think that this is a bit rough around the edges and has the potential I think to make usage of typing a significantly more frustrating experience and most of these would probably be served either by defining a protocol or by just typing it more loosely and relying on runtime behavior
It also has an effect of likely making error messages potentially incredibly difficult to follow as well (a problem with complex typing that both TypeScript and C++ have) as exploding the performance cost of type checking itself. Even if using these types are generally geared towards library authors, error messages will probably have to inevitably include data about them, which can potentially get pretty gnarly
Sure, theoretically some of these could be solved, but the developer experience with these types gets significantly more complex, especially in cases where there is judicious use of them, and I think there’s not much gain over library code that just defines the models for the queries like so
class UserFooQuery(table="user"):
# ...
select(UserFooQuery).where(...) # list[UserFooQuery]
or uses Any where appropriate. It feels like doing this is better than offloading all of this onto the type system