def uniqify(name: str, other_names: list) -> str:
    """Return a unique name with .xxx suffix if necessary.

    Example usage:

    >>> uniqify('hey', ['there'])
    'hey'
    >>> uniqify('hey', ['hey.001', 'hey.005'])
    'hey'
    >>> uniqify('hey', ['hey', 'hey.001', 'hey.005'])
    'hey.002'
    >>> uniqify('hey', ['hey', 'hey.005', 'hey.001'])
    'hey.002'
    >>> uniqify('hey', ['hey', 'hey.005', 'hey.001', 'hey.left'])
    'hey.002'
    >>> uniqify('hey', ['hey', 'hey.001', 'hey.002'])
    'hey.003'

    It also works with a dict_keys object:
    >>> uniqify('hey', {'hey': 1, 'hey.005': 1, 'hey.001': 1}.keys())
    'hey.002'
    """

    if name not in other_names:
        return name

    # Construct the list of numbers already in use.
    offset = len(name) + 1
    others = (n[offset:] for n in other_names
              if n.startswith(name + '.'))
    numbers = sorted(int(suffix) for suffix in others
                     if suffix.isdigit())

    # Find the first unused number.
    min_index = 1
    for num in numbers:
        if min_index < num:
            break
        min_index = num + 1
    return "{}.{:03d}".format(name, min_index)