Sum types (including GADTs) need to be declared (given a name), so the best you can do is to define the type outside the module and refer to it from both places, eg:
type foo = ...
module M : T with type t = foo = struct type t = foo end
But actually, depending on what you are doing, you may want to leave : T with type t = foo out altogether, and rely on the compiler to check the module signature for you.
The specification explicitaly mention that “There are no type expressions describing (defined) variant types nor record types, since those are always named, i.e. defined before use and referred to by name.” [https://caml.inria.fr/pub/docs/manual-ocaml/types.html#sss:typexpr-variant-record] But I do not understand the rationale behind this, as the polymorphic variants does not follow the same scheme.
If you ask why the manual says this even though polymorphic variants exist, it’s because that sentence is not talking about polymorphic variants I guess.
If you ask why variants and records behave that way: well, both behaviours are useful. Structural types (like objects and polymorphic variants) are more flexible and allow for nice tricks in various cases. Nominal types (like variants and records) are better-behaved; with nominal types, the type-checker tends to catch more bugs and give better error messages.