Private types can help a bit:
module M : sig
type t = private string * int
val v : string -> int -> t
end = struct
type t = string * int
let v a b = a, b
end
let f (_ : string * int) = ()
let () = f (M.v "a" 1)
Error: This expression has type M.t but an expression was expected of type
string * int
However, that’s a as-breaking change as just making the type abstract.
Edit: Alright, that’s not a warning but an error.