I’m sure I’m missing something obvious, but here we go. I defined methods that dispatch on the type of various “special matrices” from LinearAlgebra. Here is a MWE:

using LinearAlgebra
for type ∈ [:Symmetric, :LowerTriangular]
@eval f(::Type{$type{T}}) where T = T
end

The expected result is returned when called on type LowerTriangular:

julia> f(LowerTriangular{Float64})
Float64

However, when called on Symmetric, I get:

julia> f(Symmetric{Float64})
ERROR: UndefVarError: T not defined
Stacktrace:
[1] f(#unused#::Type{Symmetric{Float64, S} where S<:(AbstractMatrix{<:Float64})})
@ Main ./REPL[5]:2
[2] top-level scope
@ REPL[10]:1

Interestingly, the following implementation works:

f(::Type{Symmetric{T, S}}) where {T, S} = T
julia> f(Symmetric{Float64, Matrix{Float64}})
Float64

using LinearAlgebra
for type ∈ [:Symmetric, :LowerTriangular]
@eval f(::Type{$type{T, A}}) where {T, A} = T
end
@show f(LowerTriangular{Float64,Matrix{Float64}})
@show f(Symmetric{Float64,Matrix{Float64}})

abstract type MyAbstractTriangular{S<:AbstractMatrix} <: AbstractMatrix{eltype(S)} end

is accepted.

Edit: this seems to work, too:

struct MyTriangularMatrix{S<:AbstractMatrix} <: MyAbstractTriangular{S}
A::S
end
function MyTriangularMatrix{T}(A::Matrix{T}) where T
end
tr = MyTriangularMatrix([(1, 2) (3, 4) (5, 6)])
println()