'How to access the type of an attribute in a TypedDict?
Given a TypedDict
, how can you access/use the type of one of its attributes?
For example:
class Shape(TypedDict):
kind: Literal['square', 'circle']
x: int
y: int
KindOfShape: TypeAlias = Shape.kind # does not work - how do I do this?
kind_1: KindOfShape = 'circle'
kind_2: KindOfShape = 'spongebob' # I want this to error
Is this possible?
Solution 1:[1]
Is this possible?
No. There are 2 syntactic errors that can be summed up in 1 single sentence of PEP 589:
PEP 589 – TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys
[Class-based Syntax]
- Methods are not allowed, since
- the runtime type of a TypedDict object will always be just dict (it is never a subclass of dict).
The first syntax impossibility in the example is:
Shape.kind # does not work - how do I do this?
You don't. That's using attribute access
X.Y
, but PEP 589 is clear that theTypedDict
is a dictionary, so you'll have to use key-value dictionary access usingShape['kind']
syntaxThe
TypedDict
type hint is strict in its syntax and doesn't allow adding any methods on the declaration (or metaclass) so there's no Data Model hack that would allow using dotted attribute access syntax.So the right way to do this would be as follows:
from typing import TypedDict, Literal, TypeAlias KindOfShape: TypeAlias = Literal['square', 'circle'] class Shape(TypedDict): kind: KindOfShape x: int y: int kind_1: KindOfShape = 'circle' kind_2: KindOfShape = 'spongebob' # I want this to error
Mypy gives the exact error you want:
your module.py:14: error: Incompatible types in assignment (expression has type "Literal['spongebob']", variable has type "Union[Literal['square'], Literal['circle']]") Found 1 error in 1 file (checked 1 source file)
An argument can be made:
In my case, there are a large number of attributes; giving each their own named type would make the code less readable.
Not necessarily, you can (and often should) throw all the type hints into a stub file. It's meant to separate the static part from the run-time part. Granted, you have the extra work of writing the type hints but the whole point of using TypeAlias
is code reuse, so you'll get the extra work back from writing separate definitions.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | bad_coder |