As pointed out by Blckknght, you and Stanislav Ivanov in the comments, you can use NamedTuple:

from typing import NamedTuple


class NameInfo(NamedTuple):
    name: str
    first_letter: str


def get_info(name: str) -> NameInfo:
    return NameInfo(name=name, first_letter=name[0])

Starting from Python 3.8 you can use TypedDict which is more similar to what you want:

from typing import TypedDict


class NameInfo(TypedDict):
    name: str
    first_letter: str


def get_info(name: str) -> NameInfo:
    return {'name': name, 'first_letter': name[0]}
Top answer
1 of 3
142

As pointed out by Blckknght, you and Stanislav Ivanov in the comments, you can use NamedTuple:

from typing import NamedTuple


class NameInfo(NamedTuple):
    name: str
    first_letter: str


def get_info(name: str) -> NameInfo:
    return NameInfo(name=name, first_letter=name[0])

Starting from Python 3.8 you can use TypedDict which is more similar to what you want:

from typing import TypedDict


class NameInfo(TypedDict):
    name: str
    first_letter: str


def get_info(name: str) -> NameInfo:
    return {'name': name, 'first_letter': name[0]}
2 of 3
33

TypedDict can also be created using a typename and a dictionary where the keys are the keys and the values are the type of the values, respectively, of the dict to be returned by get_info(). This allows you to create keys that uses characters not in A-Za-z0-9_.

from typing import TypedDict

NameInfo = TypedDict('NameInfo', {'name': str, 'first-letter': str})

def get_info(name: str) -> NameInfo:
    return {'name': name, 'first-letter': name[0]}

x = get_info('cottontail')
print(x['first-letter'])   # c

Then on PyCharm, the key hint is there (also works on jupyter notebook too by pressing tab).

As a side note, if you want to see the keys of NameInfo, you can do so by assigning the returned value of a get_info call to a variable and subscript that variable. Then, most editors will show the valid keys like in the image above.

Bear in mind that type hinting is not enforced at runtime, so even if get_info is annotated to return a dict with keys (name and first_letter), nothing stops you to have it return something completely different. If get_info must return those 2 keys, you'll have to use a validator like pydantic (which is a third-party package that must be installed, e.g. pip install pydantic). A basic example is as follows. Note that this does not return a dictionary but a pydantic model (as such is not subscriptable) and will complain if any keys are missing or if the types are not what they are supposed to be etc.

from pydantic import BaseModel

class NameInfo(BaseModel):
    name: str
    first_letter: str

def get_info(name: str) -> NameInfo:
    return NameInfo(name=name, first_letter=name[0])

x = get_info('cottontail')
x.first_letter   # 'c'
x.name           # 'cottontail'

Then on for example, VSCode, the hint is there:

🌐
Python
peps.python.org › pep-0589
PEP 589 – TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys | peps.python.org
Unlike dictionary objects, dataclasses ... that implements it [1]. A TypedDict type represents dictionary objects with a specific set of string keys, and with specific value types for each valid key....
🌐
Medium
pavolkutaj.medium.com › explaining-type-hints-for-dictionaries-in-python-187d712df631
Explaining Type Hints for Dictionaries in Python | by Pavol Z. Kutaj | Medium
June 8, 2023 - def get_keys(self, key_type: KeyType) -> Dict[str, str]: Dict[str, str] is a type hint in Python that indicates a dictionary where the keys and values are both of type str.
🌐
Mypy
mypy.readthedocs.io › en › stable › cheat_sheet_py3.html
Type hints cheat sheet - mypy 1.19.1 documentation
# For most types, just use the name of the type in the annotation # Note that mypy can usually infer the type of a variable from its value, # so technically these annotations are redundant x: int = 1 x: float = 1.0 x: bool = True x: str = "test" x: bytes = b"test" # For collections on Python 3.9+, the type of the collection item is in brackets x: list[int] = [1] x: set[int] = {6, 7} # For mappings, we need the types of both keys and values x: dict[str, float] = {"field": 2.0} # Python 3.9+ # For tuples of fixed size, we specify the types of all the elements x: tuple[int, str, float] = (3, "yes
🌐
Adam Johnson
adamj.eu › tech › 2021 › 05 › 10 › python-type-hints-how-to-use-typeddict
Python type hints: How to Use TypedDict - Adam Johnson
We now arrive at solution in the title. TypedDict allows us to declare a structure for dicts, mapping their keys (strings) to the types of their values. TypedDict was specified in PEP 589 and introduced in Python 3.8.
🌐
Like Geeks
likegeeks.com › home › python › python dictionary type hinting: from dict to typeddict
Python Dictionary Type Hinting: From Dict to TypedDict
Here, the type hints enforce that all keys are integers and all values are floating-point numbers. Use nested Dict type hints for dictionaries containing other dictionaries.
Find elsewhere
🌐
Reddit
reddit.com › r/learnpython › how to type hint dictionaries without using any?
r/learnpython on Reddit: How to type hint dictionaries without using Any?
February 28, 2024 -

Hi folks I tried to keep the title as short and concise as possible, I often find myself struggling for hours in order to properly type annotate nested dictionaries in my code.

If the dict only has 1 level, it works well but with a tiny more complex ones like the following, I have a lot of trouble:

{"@context": "http://schema.org",
 "@type": "VideoObject",
 "url": "https://www.example.com/0000/adventures-music-videos.html",
 "name": "sample movie",
 "description": "example",
 "thumbnailUrl": "thumbnail.com/1.jpg",
 "uploadDate": "2023-11-29",
 "duration": "PT2H20M20S",
 "contentUrl": "sample_link",
 "isAccessibleForFree": false,
 "productionCompany": {"@type": "Organization",
  "name": "Example",
  "@id": "https://www.example.com/0000/studio/music-movies.html"},
 "hasPart": [{"@type": "Clip",
   "name": "scene 1",
   "startOffset": 15,
   "endOffset": 2126,
   "url": "https://www.example.com/0000/adventures-music-videos.html#scene_0000",
   "isAccessibleForFree": false},
  {"@type": "Clip",
   "name": "scene 2",
   "startOffset": 2128,
   "endOffset": 4114,
   "url": "https://www.example.com/0000/adventures-music-videos.html#scene_0000",
   "isAccessibleForFree": false},
  {"@type": "Clip",
   "name": "scene 3",
   "startOffset": 4117,
   "endOffset": 6055,
   "url": "https://www.example.com/0000/adventures-music-videos.html#scene_0000",
   "isAccessibleForFree": false},
  {"@type": "Clip",
   "name": "scene 4",
   "startOffset": 6057,
   "endOffset": 8414,
   "url": "https://www.example.com/0000/adventures-music-videos.html#scene_0000",
   "isAccessibleForFree": false}]}

I tried dict[str, object] and I also tried a looong annotation with all the possible types separated by a pipe, but for now the only one that does not trigger mypy in strict mode is dict[str, Any].

Any clues as to what I might be doing wrong?

🌐
Python
typing.python.org › en › latest › spec › typeddict.html
Typed dictionaries — typing documentation
It must be a dictionary display expression, not a variable or other expression that evaluates to a dictionary at runtime. The keys of the dictionary must be string literals and the values must be annotation expressions following the same rules as the class-based syntax (i.e., the qualifiers ...
🌐
Pauleveritt
pauleveritt.github.io › articles › type_hinting
Python Type Hinting — Paul Everitt documentation
In this case we see an unusual-looking structure: Dict[str, int]. Think of the values between the brackets as “arguments” to the generic Dict type. The first argument is the type of the dictionary keys.
🌐
CSDN
devpress.csdn.net › python › 63045be77e6682346619a7b2.html
How to type hint a dictionary with values of different types_python_Mangs-Python
So Pycharm remembers the keys from the dictionary literal declaration in the class's __init__, and also their values' expected types. Or rather: it expects any value to have any one of the types that are in the literal declaration - probably the same as if I had done a self.elements = {} # type: Union[type1, type2] would do. Either way, I find it super helpful. If your functions have their outputs type-hinted, then Pycharm will also take that into account.
🌐
Python documentation
docs.python.org › 3 › library › typing.html
typing — Support for type hints
# For creating a generic NamedTuple on Python 3.11 T = TypeVar("T") class Group(NamedTuple, Generic[T]): key: T group: list[T] # A functional syntax is also supported Employee = NamedTuple('Employee', [('name', str), ('id', int)]) Changed in version 3.6: Added support for PEP 526 variable annotation syntax. Changed in version 3.6.1: Added support for default values, methods, and docstrings. Changed in version 3.8: The _field_types and __annotations__ attributes are now regular dictionaries instead of instances of OrderedDict.
🌐
JetBrains
youtrack.jetbrains.com › issue › PY-36008
TypedDict: Type Hints for Dictionaries with a Fixed Set of ...
{{ (>_<) }} This version of your browser is not supported. Try upgrading to the latest stable version. Something went seriously wrong
🌐
Real Python
realpython.com › lessons › more-precise-types
More Precise Types (Video) – Real Python
So here, for Python 3.8, you would have two keys—one of "version" and "release_year"—but the values would be different types, in this case, being a string and an integer. That’s where you run into Dict having to show str and Any, like the example in the slide.
Published   November 5, 2019
🌐
Mypy
mypy.readthedocs.io › en › stable › typed_dict.html
TypedDict - mypy 1.19.1 documentation
Python programs often use dictionaries with string keys to represent objects. TypedDict lets you give precise types for dictionaries that represent objects with a fixed schema, such as {'id': 1, 'items': ['x']}.
🌐
GitHub
github.com › python › typing › issues › 28
Type for heterogeneous dictionaries with string keys · Issue #28 · python/typing
November 21, 2014 - ArgType = Dict[{'x': int, 'y': str}] def f(arg: ArgType) -> ... These types would use structural subtyping, and missing keys could plausibly be okay.
Published   Nov 21, 2014
🌐
Reddit
reddit.com › r/learnpython › type hints for a dictionary with values of different types?
r/learnpython on Reddit: Type hints for a dictionary with values of different types?
January 8, 2017 -

First, some context. I'm modeling a directory structure, and I'm thinking about how to represent a directory with either a class, a dictionary, or a named tuple. All I want to store is a name, a path, a list of files in the directory, and a list of subdirectories. If I go the class route, any function using my directory class will be annotated with the name of the class (no problems there).

def some_function(dir: Directory) -> None:
    pass

If I go the named tuple route, my directory class would look like this:

File = NamedTuple('File', [('name', str), ('path', str)])
field_list = [('name', str),
              ('path', str),
              ('files', Optional[List[File]]),
              ('subdirs', Optional[List['Directory']])]
Directory = NamedTuple('Directory', field_list)

The function definition for the named tuple version of the model would look exactly the same as for a class. I run into a problem when I want to think about this as a dictionary with type annotations. Obviously there isn't a problem making a dictionary with the same keys and values as in my named tuple, but I have no idea how to write the type annotations for a dictionary structured like that. All of the dictionary type annotations I've seen have a single type for the keys, and a single type for the values e.g. Dict[str, int]. So, how do I write type annotations for a dictionary where the values of my key-value pairs can be of different types?

🌐
Python.org
discuss.python.org › ideas
Untyped dict & walrus type hints - Ideas - Discussions on Python.org
October 1, 2023 - Adding type hints to key/value iteration over items of a dictionary whose type is unknown: for key:'str', value:'int' in untyped_dict.items(): ... Adding type hints to the walrus operator would also come in handy with untyped dicts: if ...
🌐
TestMu AI Community
community.testmuai.com › ask a question
How to Set Type Hinting for a Dictionary in Python - TestMu AI Community
January 16, 2025 - How do I set Python type hinting for a dictionary variable? Let’s say I have a dictionary like this: from typing import Dict v = { 'height': 5, 'width': 14, 'depth': 3 } result = do_something(v) def do_something(value: Dict[???]): # do stuff How do I declare the dictionary type in do_something ...