pythonpython-typinginvariantstypeddict

"dict[str, Unknown]" is incompatible with my custom TypedDict


Given this custom TypedDict TMyDict:

class TMyDict(TypedDict, total=False):
  prop_a: int
  prop_b: int

This is ok:

def get_my_dict_works() -> TMyDict:
  return {
    'prop_a': 0,
    'prop_b': 1
  }

But this don't:

def get_my_dict_fail() -> TMyDict:
  d= {
    'prop_a': 0,
    'prop_b': 1
  }
  return d

Error message is:

  Expression of type "dict[str, Unknown]" cannot be assigned to return type "TMyDict"
     "dict[str, Unknown]" is incompatible with "TMyDict"

And it works if I add the type annotation when assigning var:

def get_my_dict_fix() -> TMyDict:
  d: TMyDict = {
    'prop_a': 0,
    'prop_b': 1
  }
  return d

Why?


Solution

  • Your type checker determined the type of d before you used it

    In order to be performant and to keep type inference simple, type checkers typically only scan the code once and try to determine the type of a variable the moment it is assigned. It saw the line

    d = {
        'prop_a': 0,
        'prop_b': 1
    }
    

    and assumed that d: dict[str, int] or maybe d: dict[str, Unknown]. If the type checker tried to accept your code, it would have to jump back and check all before uses of d the moment d is used as TMyDict. This could be very costly and as just adding the annotation fixes the error, it is not supported in most type checkers. Also, the code is cleaner if the user can directly see that d is supposed to be an TMyDict instead of just any dict.