结合 mypy Union 和嵌套的 TypedDict 导致 mypy 错误:不兼容 return 值

Combining mypy Union and nested TypedDict causes mypy errror: incompatible return value

我想将 TypedDictUnion 合并。这样一个函数就可以 return AB。 Mypy 能够直接正确检测 TypedDict return 类型。但是当 TypedDict 嵌套在 Union 中时,它不起作用。

from typing_extensions import TypedDict
from typing import Union


class A(TypedDict):
    a: str


class B(TypedDict):
    b: str


def works() -> A:
    return {'a': 'value'}
    # Works as expected


def problem() -> Union[A, B]:
    return {'a': 'value'}
    # mypy_error: Incompatible return value type (got "Dict[str, str]", expected "Union[A, B]")
    # Reports an error while it should be valid


def workaround() -> Union[A, B]:
    x: A = {'a': 'value'}

    return x
    # This works again but is not very elegant

一种可能的解决方法是分配给临时 returned 类型提示变量(参见 workaround())。有更优雅的方法吗?

注:Python3.7

引自PEP 589:

An explicit [TypedDict] type annotation is generally needed, as otherwise an ordinary dictionary type could be assumed by a type checker, for backwards compatibility. When a type checker can infer that a constructed dictionary object should be a TypedDict, an explicit annotation can be omitted.

所以在代码中明确定义类型没有错。另一种可能是直接"instantiate"A

def problem() -> Union[A, B]:
    return A(a='value')

虽然这当然只是一个语法糖,在运行时将被替换为dict