Writing parameter dependent methods for abstract type

I want to write method for all subtypes of an abstract type which would make use of type parameter. Can you do that? Example, let us say we have concrete type MyType{T} and some method which needs T, like

struct MyType{T} end
Base.convert(::Type{MyType{T},::Type{S}) where {S,T} = MyType{promote_type(T,S)}

This works, but can you write it so that it works for all subtypes of some MyAbstractType? Something like (disfunctional)

abstract type MyAbstractType{T} end
Base.convert(::Type{C{T}},::Type{S}) where {S,T, C{T}<:MyAbstractType{T}} = C{promote_type(T,S)}

This seem to be decidable, but I do not know how to achieve it. Essentially, when I get as parameter type which is of form A = B{C} I need to have access to B and C separately. To get the same functionality I can just repeat definitions for all subtypes I make, but it made me curious.

C{T}<:MyAbstractType{T} asserts 1 shared leading type parameter, which is not true in general. It’s possible for subtypes to have fewer or more type parameters than a supertype:

struct A <: MyAbstractType{Int} end
struct B{S,T} <: MyAbstractType{T} end

In the former case, the defined type is not parametric. In the latter case, the iterated union with 1 unknown parameter B{S} does not share its unknown parameter with its supertype. Method signatures serve method specificity/dispatch, so static parameters represent entire types ::T or type parameters ::Vector{T}, not a fraction of unknown parametric types that match an annotation ::T{Int} or where clause expression.

That said, you’re not out of options. With the allowed ::Type{C} and C<:MyAbstractType{T}, a helper function like _stripparameter(::Type{<:MyType}) = MyType can map the concrete type C to whichever iterated union you prefer. That looks like ridiculous boilerplate, but you’d need nontrivial decisions for A or B.