Intelligent indexing

We can use Literal types to more precisely index into structured heterogeneoustypes such as tuples, NamedTuples, and TypedDicts. This feature is known asintelligent indexing.

For example, when we index into a tuple using some int, the inferred type isnormally the union of the tuple item types. However, if we want just the typecorresponding to some particular index, we can use Literal types like so:

  1. from typing import TypedDict
  2.  
  3. tup = ("foo", 3.4)
  4.  
  5. # Indexing with an int literal gives us the exact type for that index
  6. reveal_type(tup[0]) # Revealed type is 'str'
  7.  
  8. # But what if we want the index to be a variable? Normally mypy won't
  9. # know exactly what the index is and so will return a less precise type:
  10. int_index = 1
  11. reveal_type(tup[int_index]) # Revealed type is 'Union[str, float]'
  12.  
  13. # But if we use either Literal types or a Final int, we can gain back
  14. # the precision we originally had:
  15. lit_index: Literal[1] = 1
  16. fin_index: Final = 1
  17. reveal_type(tup[lit_index]) # Revealed type is 'str'
  18. reveal_type(tup[fin_index]) # Revealed type is 'str'
  19.  
  20. # We can do the same thing with with TypedDict and str keys:
  21. class MyDict(TypedDict):
  22. name: str
  23. main_id: int
  24. backup_id: int
  25.  
  26. d: MyDict = {"name": "Saanvi", "main_id": 111, "backup_id": 222}
  27. name_key: Final = "name"
  28. reveal_type(d[name_key]) # Revealed type is 'str'
  29.  
  30. # You can also index using unions of literals
  31. id_key: Literal["main_id", "backup_id"]
  32. reveal_type(d[id_key]) # Revealed type is 'int'