@@ -128,6 +128,9 @@ Person({"name": "Alice"})
128128accepts_person({" name" : " Alice" })
129129# TODO : this should be an error, similar to the above
130130house.owner = {" name" : " Alice" }
131+ a_person: Person
132+ # TODO : this should be an error, similar to the above
133+ a_person = {" name" : " Alice" }
131134```
132135
133136All of these have an invalid type for the ` name ` field:
@@ -144,6 +147,9 @@ Person({"name": None, "age": 30})
144147accepts_person({" name" : None , " age" : 30 })
145148# TODO : this should be an error, similar to the above
146149house.owner = {" name" : None , " age" : 30 }
150+ a_person: Person
151+ # TODO : this should be an error, similar to the above
152+ a_person = {" name" : None , " age" : 30 }
147153```
148154
149155All of these have an extra field that is not defined in the ` TypedDict ` :
@@ -160,6 +166,9 @@ Person({"name": "Alice", "age": 30, "extra": True})
160166accepts_person({" name" : " Alice" , " age" : 30 , " extra" : True })
161167# TODO : this should be an error
162168house.owner = {" name" : " Alice" , " age" : 30 , " extra" : True }
169+ # TODO : this should be an error
170+ a_person: Person
171+ a_person = {" name" : " Alice" , " age" : 30 , " extra" : True }
163172```
164173
165174## Type ignore compatibility issues
@@ -242,8 +251,9 @@ invalid_extra = OptionalPerson(name="George", extra=True)
242251
243252## ` Required ` and ` NotRequired `
244253
245- You can have fine-grained control over field requirements using ` Required ` and ` NotRequired `
246- qualifiers, which override the class-level ` total= ` setting:
254+ You can have fine-grained control over keys using ` Required ` and ` NotRequired ` qualifiers. These
255+ qualifiers override the class-level ` total ` setting, which sets the default (` total=True ` means that
256+ all keys are required by default, ` total=False ` means that all keys are non-required by default):
247257
248258``` py
249259from typing_extensions import TypedDict, Required, NotRequired
@@ -444,6 +454,12 @@ class Person(TypedDict, total=False):
444454 id : ReadOnly[Required[int ]]
445455 name: str
446456 age: int | None
457+
458+ alice: Person = {" id" : 1 , " name" : " Alice" , " age" : 30 }
459+ alice[" age" ] = 31 # okay
460+
461+ # TODO : this should be an error
462+ alice[" id" ] = 2
447463```
448464
449465## Methods on ` TypedDict `
@@ -764,6 +780,38 @@ from typing import TypedDict
764780x: TypedDict = {" name" : " Alice" }
765781```
766782
783+ ### ` dict ` -subclass inhabitants
784+
785+ Values that inhabit a ` TypedDict ` type must be instances of ` dict ` itself, not a subclass:
786+
787+ ``` py
788+ from typing import TypedDict
789+
790+ class MyDict (dict ):
791+ pass
792+
793+ class Person (TypedDict ):
794+ name: str
795+ age: int | None
796+
797+ # TODO : this should be an error
798+ x: Person = MyDict({" name" : " Alice" , " age" : 30 })
799+ ```
800+
801+ ### Cannot be used in ` isinstance ` tests
802+
803+ ``` py
804+ from typing import TypedDict
805+
806+ class Person (TypedDict ):
807+ name: str
808+ age: int | None
809+
810+ def _ (obj : object ) -> bool :
811+ # TODO : this should be an error
812+ return isinstance (obj, Person)
813+ ```
814+
767815## Diagnostics
768816
769817<!-- snapshot-diagnostics -->
0 commit comments