@@ -4264,7 +4264,8 @@ e: MovieFunctional = {"name": "Blade Runner", "year": 1982} # error: [invalid-k
42644264always implicitly non-required.
42654265
42664266``` py
4267- from typing_extensions import TypedDict, ReadOnly, Required, NotRequired
4267+ from typing_extensions import TypedDict, ReadOnly, Required, NotRequired, ClassVar, Final
4268+ from dataclasses import InitVar
42684269
42694270# OK
42704271class A (TypedDict , extra_items = int ):
@@ -4274,13 +4275,25 @@ class A(TypedDict, extra_items=int):
42744275class B (TypedDict , extra_items = ReadOnly[int ]):
42754276 name: str
42764277
4277- # TODO : should be error: [invalid-typed-dict-header]
4278+ # error: [invalid-type-form] "Type qualifier `typing.Required` is not valid in a TypedDict `extra_items` argument"
42784279class C (TypedDict , extra_items = Required[int ]):
42794280 name: str
42804281
4281- # TODO : should be error: [invalid-typed-dict-header]
4282+ # error: [invalid-type-form] "Type qualifier `typing.NotRequired` is not valid in a TypedDict `extra_items` argument"
42824283class D (TypedDict , extra_items = NotRequired[int ]):
42834284 name: str
4285+
4286+ # error: [invalid-type-form] "Type qualifier `typing.ClassVar` is not valid in a TypedDict `extra_items` argument"
4287+ class D (TypedDict , extra_items = ClassVar[int ]):
4288+ name: str
4289+
4290+ # error: [invalid-type-form] "Type qualifier `typing.Final` is not valid in a TypedDict `extra_items` argument"
4291+ class D (TypedDict , extra_items = Final[int ]):
4292+ name: str
4293+
4294+ # error: [invalid-type-form] "Type qualifier `dataclasses.InitVar` is not valid in a TypedDict `extra_items` argument"
4295+ class D (TypedDict , extra_items = InitVar[int ]):
4296+ name: str
42844297```
42854298
42864299It is an error to specify both ` closed ` and ` extra_items ` :
@@ -4291,6 +4304,62 @@ class E(TypedDict, closed=True, extra_items=int):
42914304 name: str
42924305```
42934306
4307+ ### Forward references in ` extra_items `
4308+
4309+ Stringified forward references are understood:
4310+
4311+ ` a.py ` :
4312+
4313+ ``` py
4314+ from typing import TypedDict
4315+
4316+ class F (TypedDict , extra_items = " F | None" ): ...
4317+ ```
4318+
4319+ While invalid syntax in forward annotations is rejected:
4320+
4321+ ` b.py ` :
4322+
4323+ ``` py
4324+ from typing import TypedDict
4325+
4326+ # error: [invalid-syntax-in-forward-annotation]
4327+ class G (TypedDict , extra_items = " not a type expression" ): ...
4328+ ```
4329+
4330+ In non-stub files, forward references in ` extra_items ` must be stringified:
4331+
4332+ ` c.py ` :
4333+
4334+ ``` py
4335+ from typing import TypedDict
4336+
4337+ # error: [unresolved-reference] "Name `H` used when not defined"
4338+ class H (TypedDict , extra_items = H | None ): ...
4339+ ```
4340+
4341+ but stringification is unnecessary in stubs:
4342+
4343+ ` stub.pyi ` :
4344+
4345+ ``` pyi
4346+ from typing import TypedDict
4347+
4348+ class I (TypedDict , extra_items = I | None ): ...
4349+ ```
4350+
4351+ The ` extra_items ` keyword is not parsed as an annotation expression for non-TypedDict classes:
4352+
4353+ ` d.py ` :
4354+
4355+ ``` py
4356+ class TypedDict : # not typing.TypedDict!
4357+ def __init_subclass__ (cls , extra_items : int ): ...
4358+
4359+ class Foo (TypedDict , extra_items = 42 ): ... # fine
4360+ class Bar (TypedDict , extra_items = int ): ... # error: [invalid-argument-type]
4361+ ```
4362+
42944363### Writing to an undeclared literal key of an ` extra_items ` TypedDict is allowed, if the type is assignable
42954364
42964365``` py
0 commit comments