get_a(baz::Baz) baz.bar.foo.a was my counter example, to show what was a bad idea.
See the code example in the initial post for the full example but what i do think might be a good idea is this:
abstract type FooSubtype <: AbstractFoo end
Base.getproperty(sub::FooSubtype, s::Symbol) = get(sub, Val(s))
# In the base-type, a fallback accessor is defined
get(sub::FooSubtype, ::Val{T}) where {T} = getfield(sub, T)
get(sub::FooSubtype, ::Val{:a}) = sub.foo.a
Base.setproperty!(sub::FooSubtype, s::Symbol, x) = set!(sub, Val(s), x)
# In the base-type, a fallback accessor is defined
set!(sub::FooSubtype, ::Val{T}, x) where {T} = setfield!(sub, T, x)
set!(sub::FooSubtype, ::Val{:a}, x) = sub.foo.a = x
This is basically the multiple dispatch version of what you suggested earlier