from typing import Union


def coerce_number(
    input_value: Union[str, int, float, bool, None]
) -> Union[int, float, str, None]:
    """
    Try to coerce a str literal to an int/float

    If coercion is not possible return the original input value
    """
    # Don't try to convert None or values that are already numeric
    # in order to preserve precision
    if input_value is None:
        return input_value

    if isinstance(input_value, (int, float)):
        return input_value

    i_value = None
    f_value = None
    try:
        f_value = float(input_value)
        i_value = int(input_value)
    except ValueError:
        pass

    # Input was a non-coercable str
    if (i_value is None) and (f_value is None):
        new_value = input_value
    # Input was an int
    elif i_value == f_value:
        new_value = i_value
    # Input was a float
    else:
        new_value = f_value

    return new_value