@@ -83,6 +83,7 @@ CAPITALIZED_NAME = "Name"
8383
8484# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "Name" - did you mean "name"?"
8585# error: [missing-typed-dict-key] "Missing required key 'name' in TypedDict `Person` constructor"
86+ # error: [invalid-assignment]
8687dave: Person = {CAPITALIZED_NAME : " Dave" , " age" : 20 }
8788
8889def age () -> Literal[" age" ] | None :
@@ -95,30 +96,33 @@ The construction of a `TypedDict` is checked for type correctness:
9596
9697``` py
9798# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`"
99+ # error: [invalid-assignment]
98100eve1a: Person = {" name" : b " Eve" , " age" : None }
101+
99102# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`"
100103eve1b = Person(name = b " Eve" , age = None )
101104
102- # TODO should reveal Person (should be fixed by implementing assignability for TypedDicts)
103- reveal_type(eve1a) # revealed: dict[Unknown | str, Unknown | bytes | None]
105+ reveal_type(eve1a) # revealed: Person
104106reveal_type(eve1b) # revealed: Person
105107
106108# error: [missing-typed-dict-key] "Missing required key 'name' in TypedDict `Person` constructor"
109+ # error: [invalid-assignment]
107110eve2a: Person = {" age" : 22 }
111+
108112# error: [missing-typed-dict-key] "Missing required key 'name' in TypedDict `Person` constructor"
109113eve2b = Person(age = 22 )
110114
111- # TODO should reveal Person (should be fixed by implementing assignability for TypedDicts)
112- reveal_type(eve2a) # revealed: dict[Unknown | str, Unknown | int]
115+ reveal_type(eve2a) # revealed: Person
113116reveal_type(eve2b) # revealed: Person
114117
115118# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
119+ # error: [invalid-assignment]
116120eve3a: Person = {" name" : " Eve" , " age" : 25 , " extra" : True }
121+
117122# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
118123eve3b = Person(name = " Eve" , age = 25 , extra = True )
119124
120- # TODO should reveal Person (should be fixed by implementing assignability for TypedDicts)
121- reveal_type(eve3a) # revealed: dict[Unknown | str, Unknown | str | int]
125+ reveal_type(eve3a) # revealed: Person
122126reveal_type(eve3b) # revealed: Person
123127```
124128
@@ -201,6 +205,8 @@ reveal_type(alice["inner"]["age"]) # revealed: int | None
201205reveal_type(alice[" inner" ][" non_existing" ]) # revealed: Unknown
202206
203207# error: [invalid-key] "Invalid key for TypedDict `Inner`: Unknown key "extra""
208+ # error: [invalid-argument-type]
209+ # error: [invalid-assignment]
204210alice: Person = {" inner" : {" name" : " Alice" , " age" : 30 , " extra" : 1 }}
205211```
206212
@@ -237,64 +243,88 @@ All of these are missing the required `age` field:
237243
238244``` py
239245# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `Person` constructor"
246+ # error: [invalid-assignment]
240247alice2: Person = {" name" : " Alice" }
248+
241249# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `Person` constructor"
242250Person(name = " Alice" )
251+
243252# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `Person` constructor"
244253Person({" name" : " Alice" })
245254
246255# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `Person` constructor"
256+ # error: [invalid-argument-type]
247257accepts_person({" name" : " Alice" })
248258
249- # TODO : this should be an error, similar to the above
259+ # TODO : this should be an invalid-key error, similar to the above
260+ # error: [invalid-assignment]
250261house.owner = {" name" : " Alice" }
251262
252263a_person: Person
253264# error: [missing-typed-dict-key] "Missing required key 'age' in TypedDict `Person` constructor"
265+ # error: [invalid-assignment]
254266a_person = {" name" : " Alice" }
255267```
256268
257269All of these have an invalid type for the ` name ` field:
258270
259271``` py
260272# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
273+ # error: [invalid-assignment]
261274alice3: Person = {" name" : None , " age" : 30 }
275+
262276# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
263277Person(name = None , age = 30 )
278+
264279# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
265280Person({" name" : None , " age" : 30 })
266281
267282# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
283+ # error: [invalid-argument-type]
268284accepts_person({" name" : None , " age" : 30 })
269- # TODO : this should be an error, similar to the above
285+
286+ # TODO : this should be an invalid-key error
287+ # error: [invalid-assignment]
270288house.owner = {" name" : None , " age" : 30 }
271289
272290a_person: Person
273291# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
292+ # error: [invalid-assignment]
274293a_person = {" name" : None , " age" : 30 }
294+
275295# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Person`: value of type `None`"
296+ # error: [invalid-assignment]
276297(a_person := {" name" : None , " age" : 30 })
277298```
278299
279300All of these have an extra field that is not defined in the ` TypedDict ` :
280301
281302``` py
282303# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
304+ # error: [invalid-assignment]
283305alice4: Person = {" name" : " Alice" , " age" : 30 , " extra" : True }
306+
284307# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
285308Person(name = " Alice" , age = 30 , extra = True )
309+
286310# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
287311Person({" name" : " Alice" , " age" : 30 , " extra" : True })
288312
289313# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
314+ # error: [invalid-argument-type]
290315accepts_person({" name" : " Alice" , " age" : 30 , " extra" : True })
291- # TODO : this should be an error
316+
317+ # TODO : this should be an invalid-key error
318+ # error: [invalid-assignment]
292319house.owner = {" name" : " Alice" , " age" : 30 , " extra" : True }
293320
294321a_person: Person
295322# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
323+ # error: [invalid-assignment]
296324a_person = {" name" : " Alice" , " age" : 30 , " extra" : True }
325+
297326# error: [invalid-key] "Invalid key for TypedDict `Person`: Unknown key "extra""
327+ # error: [invalid-assignment]
298328(a_person := {" name" : " Alice" , " age" : 30 , " extra" : True })
299329```
300330
@@ -760,6 +790,7 @@ class Employee(Person):
760790alice: Employee = {" name" : " Alice" , " employee_id" : 1 }
761791
762792# error: [missing-typed-dict-key] "Missing required key 'employee_id' in TypedDict `Employee` constructor"
793+ # error: [invalid-assignment]
763794eve: Employee = {" name" : " Eve" }
764795
765796def combine (p : Person, e : Employee):
@@ -861,6 +892,7 @@ p1: TaggedData[int] = {"data": 42, "tag": "number"}
861892p2: TaggedData[str ] = {" data" : " Hello" , " tag" : " text" }
862893
863894# error: [invalid-argument-type] "Invalid argument to key "data" with declared type `int` on TypedDict `TaggedData`: value of type `Literal["not a number"]`"
895+ # error: [invalid-assignment]
864896p3: TaggedData[int ] = {" data" : " not a number" , " tag" : " number" }
865897
866898class Items (TypedDict , Generic[T]):
@@ -894,6 +926,7 @@ p1: TaggedData[int] = {"data": 42, "tag": "number"}
894926p2: TaggedData[str ] = {" data" : " Hello" , " tag" : " text" }
895927
896928# error: [invalid-argument-type] "Invalid argument to key "data" with declared type `int` on TypedDict `TaggedData`: value of type `Literal["not a number"]`"
929+ # error: [invalid-assignment]
897930p3: TaggedData[int ] = {" data" : " not a number" , " tag" : " number" }
898931
899932class Items[T](TypedDict):
@@ -928,6 +961,9 @@ grandchild: Node = {"name": "grandchild", "parent": child}
928961nested: Node = {" name" : " n1" , " parent" : {" name" : " n2" , " parent" : {" name" : " n3" , " parent" : None }}}
929962
930963# error: [invalid-argument-type] "Invalid argument to key "name" with declared type `str` on TypedDict `Node`: value of type `Literal[3]`"
964+ # error: [invalid-assignment]
965+ # error: [invalid-argument-type]
966+ # error: [invalid-argument-type]
931967nested_invalid: Node = {" name" : " n1" , " parent" : {" name" : " n2" , " parent" : {" name" : 3 , " parent" : None }}}
932968```
933969
@@ -977,7 +1013,7 @@ class Person(TypedDict):
9771013 name: str
9781014 age: int | None
9791015
980- # TODO : this should be an error
1016+ # error: [invalid-assignment] "Object of type `MyDict` is not assignable to `Person`"
9811017x: Person = MyDict({" name" : " Alice" , " age" : 30 })
9821018```
9831019
@@ -1029,8 +1065,12 @@ def write_to_non_literal_string_key(person: Person, str_key: str):
10291065 person[str_key] = " Alice" # error: [invalid-key]
10301066
10311067def create_with_invalid_string_key ():
1032- alice: Person = {" name" : " Alice" , " age" : 30 , " unknown" : " Foo" } # error: [invalid-key]
1033- bob = Person(name = " Bob" , age = 25 , unknown = " Bar" ) # error: [invalid-key]
1068+ # error: [invalid-key]
1069+ # error: [invalid-assignment]
1070+ alice: Person = {" name" : " Alice" , " age" : 30 , " unknown" : " Foo" }
1071+
1072+ # error: [invalid-key]
1073+ bob = Person(name = " Bob" , age = 25 , unknown = " Bar" )
10341074```
10351075
10361076Assignment to ` ReadOnly ` keys:
0 commit comments