I have a couple of TypedDict
s for use in type hinting that are supposed to have some sets of incompatible keys.
For example, if I need to specify that a particular dict
can have bar
or baz
but not both of them, I can write two TypedDict
s:
from typing import TypedDict
class Foo1(TypedDict):
bar: str
class Foo2(TypedDict):
baz: int
Foo = Foo1 | Foo2
foo_instance_1: Foo = { # Works fine
'bar': 'foobar'
}
foo_instance_2: Foo = { # Also fine
'baz': 42
}
foo_instance_3: Foo = { # Warning: Expected type 'Foo1 | Foo2', got 'dict[str, str | int]' instead
'bar': 'foobar',
'baz': 42
}
However, this doesn’t scale very well if I were to have multiple sets; for example, a simple multiplication shows that three sets of 2, 3 and 4 keys each will result in 24 {{{TypedDict}}}s. A solution would be:
class Foo(TypedDict):
bar: IncompatibleWith('baz', 'qux')[str]
baz: IncompatibleWith('bar', 'qux')[int]
qux: IncompatibleWith('bar', 'baz')[bool]
…or, with a decorator somewhat similar to @overload
:
@incompatible('bar', 'baz', 'qux')
# ...
class Foo(TypedDict):
bar: str
baz: int
qux: bool
I asked this question on StackOverflow and was informed that such a feature doesn’t exist. How about adding it to Python then?