Thank you for your efforts! I'm glad to see this promising attempt to allow using TypedDict for **kwargs precise typing. It is amazing, I have seen many use cases for that, often to make stub code more DRY and close to the original implementation (requests, where get, post, etc. share signature [1], django-stubs with model fields - more than 10 arguments with non-trivial signatures [2]).

I have a question regarding point 3 in the "assignment" chapter. Why should this be considered safe? mypy rejects the following code:

def foo(*, title: str, year: int = ...) -> int:  # same as **kwargs: **Movie
    ...
def bar(title: str, year: int = ...) -> int:
    ...
bar = foo  # E: Incompatible types in assignment (expression has type "Callable[[NamedArg(str, 'title'), DefaultNamedArg(int, 'year')], int]", variable has type "Callable[[str, int], int]")

The reason is that foo('a', 0) was allowed before assignment and fails after it (positional-or-keyword parameters should not be substituted with keyword-only). So why should essentially the same code be allowed with TypedDict?
def foo(**kwargs: **Movie): ...
def bar(title: str, year: int = ...): ...
bar = foo  # OK!  # <-- Why is it allowed?

I think that keyword-only notation must be required in this case for consistency and will be more semantically correct.
I apologise in advance for any mistakes here - I haven't participated in typing-sig before.

[1] https://github.com/python/typeshed/blob/master/stubs/requests/requests/sessions.pyi#L119=
[2] https://github.com/typeddjango/django-stubs/blob/master/django-stubs/db/models/fields/__init__.pyi#L262=