如何键入接受联合和任何类型的联合的提示函数?

How to type hint function accepting both union and any type of that union?

$ cat foo.py

from typing import overload, Union, TypeVar

T = Union[int, str]
SubT = TypeVar("SubT", int, str)

@overload
def a(t: T) -> T:
    ...

@overload
def a(t: SubT) -> SubT:
    ...

def a(t: T) -> T:
    return t
$ mypy foo.py

foo.py:7: error: Overloaded function signatures 1 and 2 overlap with incompatible return types

为什么 return 类型不兼容,我该如何进行类型检查?我想要这些示例 return 类型:

v_1: Union[int, str] = 1
v_2: int = 2
v_3: str = "3"

a(v_1)  # Want Union[int, str].
a(v_2)  # Want int.
a(v_3)  # Want str.

我想避免为 intstr 显式重载 a,因为 SubT 实际上有两个以上的约束。

如果我删除第一个重载,a(v_1) 将不会进行类型检查。如果我删除第二个重载,a(v_2)a(v_3) 会将它们的 return 值类型分别提示为 Union[int, str] 而不是 intstr

在我的实际问题中,我有一个 IterableSubT 下的同类类型(TypeVar)或 T 下的异构类型(Union).我想写一个a,如果它出现在同类情况下,它将对两者的元素进行操作而不会丢失类型粒度。

TypeVar 将允许您提供联合类型和联合本身作为选项:

T = TypeVar("T", int, str, Union[int, str])

def a(t: T) -> T:
    return t