Thanks to both of you for the replies. Module M contains a lot of functions for the simulation of dynamical models. Outside M, users are required to define some specific types to be consistent with another historical project. The definition of these types should be kept as simple as possible, this may look a bit odd, but forcing the user to define a type T1 <: AT1 is already too much, which is why Mauro's suggestion is not an option for me (but thanks anyway for the proposal!).
And the tricky thing is that T1 and T2 can't be initialized before the module, so I can't do: type T1 a::Float64 end type T2 b::Float64 end module M import Main.T1, Main.T2 function f(x::T1) return x.a end function f(x::T2) return x.b + 1 end export f end using M t1 = T1(1.0) t2 = T2(2.0) println(f(t1)) println(f(t2)) which works. If there is no solution similar to the first code I proposed, I think I'll simply use two different names such as f1(x::T1) and f2(x::T2) in M. But new suggestions are still highly appreciated :) Many thanks.