Description
I've recently been reading Python code where heterogeneous dictionary objects are used a lot. I mean cases like this:
foo({'x': 1, 'y': 'z'})
The value for key 'x'
must be an integer and the value for key 'z'
must be a string. Currently there is no precise way of specifying the type of the argument to foo
in the above example. In general, we'd have to fall back to Dict[str, Any]
, Mapping[str, Union[int, str]]
or similar. This loses a lot of information.
However, we could support such types. Here is a potential syntax:
def foo(arg: Dict[{'x': int, 'y': str}]) -> ...: ...
Of course, we could also allow Dict[dict(x=int, y=str)]
as an equivalent. I don't really love either syntax, though.
Alternatively, we could omit Dict[...]
as redundant:
def f(arg: dict(x=int, y=str)) -> ...
Using type aliases would often be preferred:
ArgType = Dict[{'x': int, 'y': str}]
def f(arg: ArgType) -> ...
These types would use structural subtyping, and missing keys could plausibly be okay. So Dict[dict(x=int, y=str)]
could be a subtype of Dict[dict(x=int)]
, and vice versa (!).
Maybe there should also be a way of deriving subtypes of heterogeneous dictionary types (similar to inheritance) to avoid repetition.
Maybe we'd also want to support Mapping[...]
variants (for read-only access and covariance).
Some existing languages have types resembling these (at least Hack and TypeScript, I think).