This question is similar to Python Typing: declare return value type based on function argument but different enough that it doesn't fit into a comment.
I have the following function:
T = TypeVar('T', dict, str)
def fun(t: T) -> T:
if t == dict:
return {"foo": "bar"}
else:
return "foo"
I'd like to be able to call it like this:
a_string = fun(str)
a_dict = fun(dict)
Pylance throws this error on the second line:
Expression of type "dict[str, str]" cannot be assigned to return type "T@fun"
And this error on the last line:
Expression of type "Literal['foo']" cannot be assigned to return type "T@fun"
According to this answer, I should be able to do something like this:
T = TypeVar('T', dict, str)
def fun(t: Type[T]) -> T:
if t == dict:
return t({"foo": "bar"})
else:
return t("foo")
This removes the error on the second line but causes a different error on the last line:
No overloads for "__init__" match the provided arguments
Argument types: (Literal['foo'])
I studied this answer for a long time before I was finally able to make it work:
T = TypeVar('T', dict, str)
def fun(t: Callable[..., T]) -> T:
if t == dict:
return t({"foo": "bar"})
else:
return t("foo")
The problem with this is I don't understand why it works. And I don't understand why the others don't.