I think the answer is that numeric is always a double precision floating point number, you can assign integer values to it, but they are represented internally as double precision floating point numbers.
vctrs gives you vec_ptype_common(1L,1) that you can use to find common compatible class.
In this case numeric/double as integers can be freely translated to those.
some notes from the purrr package's deprecated is_numeric function:
#'
#' Numeric is used in three different ways in base R:
#' * as an alias for double (as in [as.numeric()])
#' * to mean either integer or double (as in [mode()])
#' * for something representable as numeric (as in [as.numeric()])
#' This function tests for the second, which is often not what you want
#' so these functions are deprecated.
#'
#' @export
#' @keywords internal
is_numeric <- function(x) {
warning("Deprecated", call. = FALSE)
is_integer(x) || is_double(x)
}