With regards to choosing AbstractArray rather than Array, consider that there are many subtypes of AbstractArray that may not appear relevant when first writing your algorithm, but that generalizing to is very convenient (Adjoint, UniformScaling, Diagonal, StaticArray just to name a few!).
If the first argument must be a complex number (that is, real arguments are completely not allowed ever), then it makes sense to restrict it. Otherwise, go with Number (which already is the supertype of Real and Complex, so no need to define CR). For the other arguments, restricting to Float64 is almost never a good idea in practice. Should your algorithm really fail if the inputs are integers, or would all of the math “just work” anyway? I would probably consider a signature like this (again, assuming complex is absolutely required for the first one, otherwise I would leave that eltype off as well)
function S2S(Sₐ::AbstractArray{<:Complex, 3}, Zₐ::AbstractMatrix, Zᵦ::AbstractMatrix)
...
end
function S2S(Sₐ::AbstractMatrix{<:Complex}, Zₐ::AbstractVector, Zᵦ::AbstractVector)
...
end