Python Typing: declare return value type based on function argument
You are looking for typing.Type
, so something to the effect of:
from typing import TypeVar, Type
T = TypeVar("T", str, complex, float, int)
def fun(t: Type[T]) -> T:
return t(42)
fun(int)
fun(float)
fun(complex)
fun(str)
Note, your type variable needs to be constrained, because not all Type
objects accept arguments, but you can constrain it to a few that do like your example.
TLDR: You need a TypeVar
for the return type of calling t
:
def fun(t: Callable[[int], R]) -> R:
...
Constraining on a type is too restrictive here. The function accepts any Callable
that takes an integer, and the return type of the function is that of the Callable
. This can be specified using a TypeVar
for the return type:
from typing import Callable, TypeVar
R = TypeVar('R') # the variable return type
def fun(t: Callable[[int], R]) -> R:
return t(42)
fun(int) # Revealed type is 'builtins.int*'
fun(float) # Revealed type is 'builtins.float*'
reveal_type(fun(lambda x: str(x))) # Revealed type is 'builtins.str*'
This works for types as well, because type instantiation is a call.
If a more complex signature, e.g. with keyword arguments, is needed, use Protocol
(from typing
or typing_extensions
).
Note that if one explicitly wants to pass only 42
to the Callable
, Literal
(from typing
or typing_extensions
) can be used to specify that.
R = TypeVar('R')
def fun(t: Callable[[Literal[42]], R]) -> R:
return t(42)
Note that any function of the type Callable[[int], R]
also satisfies Callable[[Literal[42]], R]
.