basedmypy
basedmypy copied to clipboard
A `MappedType` type
Like TypedDict but based.
- Support any
Mappingincluding a covariant version ofdict - Usable as a type parameter on functions unrelated to maps
- Support any key type
- Control over additional keys
- exclude additional keys
- specify type bounds
class Foo(MappedType):
a: int
f: defaultdict[Foo.Key, Foo.Value] = defaultdict(None, a=1)
reveal_type(f) # defaultdict & Foo
def foo(a: Foo.Key) -> Foo.Value: ...
foo('a') # int
class Foo(MappedType):
Key[1]: int
Or
@dataclass
class Thing:
key: type
value: type
KV = MappedTypeVar("KV", Thing("hi", str), Thing("bye", int))
# Alternative shorthand
# KV = MappedTypeVar("KV", mapping={"hi": str, "bye": int})
def foo(k: KV.key) -> KV.value: ...
reveal_type(foo("hi")) # str
reveal_type(foo("bye")) # int
def bar(k: KV.key, v: KV.value): ...
bar("hi", 1) # error, expected str, found int
class A:
def __getattr__(self, item: KV.key) -> KV.value: ...
a = A()
reveal_type(a.hi) # str
ListY = TypeVar("ListY", [1, 2, 3], [2, 3, 4])
def bar_y(k: KVX[0], v: KVX[1]) -> KVX[2]: ...
bar_y(2, 3) # 4
Prior art
TS be like
type Thing = {
hi: string
bye: nuber
}
declare function foo<K extends keyof Thing>(t: K) -> Thing[K]
This has the limitation of only being key/value where the key is string | number | Symbol.