This does not completely answer your question, but note that
julia> Union{Missing, Any}
Any
and thus
julia> Vector{Union{Missing, Any}}
Array{Any,1}
so your function only accepts objects with type Array{Any,1} (Vector{Any}). Note also that
julia> Vector{Int} <: Vector{Any}
false
since Julias type parameters are invariant, see relevant manual section: Types · The Julia Language and thus
julia> f(x::Vector{Any}) = println("hi");
julia> f(Any[1, 2]) # typeof(x) == Vector{Any} so this works
hi
julia> f(Int[1, 2]) # typeof(x) == Vector{Int} so this fails
ERROR: MethodError: no method matching f(::Array{Int64,1})
I see, so if I undestand correctly, there are no specific type for “missing” that would not be “any”? In other words, “any-with-missing” and “any-without-missing” are not dissociated?
Indeed, since (as its name indicates) Any can be any value, including missing.
In general, use ::AbstractArray{>:Missing} to define a method which should be called for any array which can contain missing. But note that in many cases you can just define a single generic method, knowing that the compiler will (often) optimize out ismissing(A[i]) calls when the array cannot contain missing.
Sure, you can write f(X::AbstractVector{<:Real}; n::Integer=10) if you want, but often it is not necessary to specify types. (If you want to do something completely different with strings, then it is possible to do that with a more specific method, but maybe it would be better to create a new function entirely?)
Number includes complex numbers, which do not support maximum or minimum.
On the other hand, if somebody creates a non-number type which supports maximum, minimum and range, then why not allow it in your function?
::AbstractVector{<:Union{Number, Missing}} is the way to go if you want numbers or missing values. But it can also make sense to define two methods instead, depending on what the function does. Note that in the example you provide, the call to collect around skipmissing isn’t needed since maximum accepts any iterable: if you define an internal method which takes any iterable too, and call it from the two public methods, you can avoid that unnecessary allocation.