python / python/mypy

Generic TypedDict and inferring return value

Open
#17,753 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
20.6k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

I was working on some code that needs to be passed a generic TypedDict, like this:

from typing import TypeVar, TypedDict, Generic

T = TypeVar("T")

ReturnValue = TypeVar("ReturnValue")


class Option(TypedDict, Generic[ReturnValue]):
    name: str
    value: ReturnValue


class Menu:
    def ask(self, text: str, options: list[Option[T]]) -> T:
        return options[0]["value"]

And the usage would be this:

value = Menu().ask("text", [{"value": 123, "name": "abc"}])

reveal_type(value)

In this case the value type should int, but unfortunately I get this error:

main.py:18: error: Need type annotation for "value"  [var-annotated]
main.py:18: error: Argument 2 to "ask" of "Menu" has incompatible type "list[dict[str, int]]"; expected "list[Option[Never]]"  [arg-type]

Playground: https://mypy-play.net/?mypy=latest&python=3.12&flags=verbose%2Cstrict&gist=9a8643b51a69f6d60ab5b0b482e10865

This seems to be working well in pyright 😊

Also I didn't find yet a workaround, changing the class to this:

class Menu:
    def ask(self, text: str, options: list[dict[str, T]]) -> T:
        return options[0]["value"]

Almost works, but for example in the case above it would infer the type as object 😊

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal Python example and the linked mypy-play reproduction to confirm the current inference errors. Trace the type inference involved in generic TypedDict arguments, then verify that the example infers value as int without requiring an annotation or reporting an incompatible argument error.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.