It is actually not needed there. It is the same as doing this (which highlights the fact that you have to be careful with the fact that a new array was defined):

julia> import Base:deleteat!
julia> using SparseArrays
julia> function deleteat!(x::SparseVector,ind)
ind_sparse = findfirst(isequal(ind),x.nzind)
deleteat!(x.nzval,ind_sparse)
deleteat!(x.nzind,ind_sparse)
return SparseVector(x.n-1,x.nzind,x.nzval)
end
deleteat! (generic function with 9 methods)
julia> x = sparse([0,1,0,1,0])
5-element SparseVector{Int64, Int64} with 2 stored entries:
[2] = 1
[4] = 1
julia> x = deleteat!(x,4)
4-element SparseVector{Int64, Int64} with 1 stored entry:
[2] = 1

function deleteat(x::SparseVector,ind)
ind_sparse = findfirst(isequal(ind),x.nzind)
deleteat!(x.nzval,ind_sparse)
deleteat!(x.nzind,ind_sparse)
return SparseVector(x.n-1,x.nzind,x.nzval)
end
function deleteat!(x::Sparsevector,ind)
x = deleteat(x,ind)
end

So that whatever the vector, calling deleteat!() has the same behavior ? Of course, this masks the fact that the vector has to be redefined.

No, that will be the same. You cannot really have the same interface, because the SparseVector is immutable (it contains mutable fields, but the n field is not mutable). You have to return x and reassign it on return, in any case. (that probably explains why there is no deleteat! defined by default for sparse vectors).