Is it possible to add a type annotation for partial/not-total typeddicts?

I want add a type annotation to the following function:

def dict_not_none(**kwargs: Any) -> ???:
    return {k: v for k, v in kwargs.items() if v is not None}

Which allows static type checkers like mypy and pyright to understand the function, particularly in regards to TypedDicts.

Using an example from some real code, I have:

class BoolSchema(TypedDict, total=False):
    type: Required[Literal['bool']]
    strict: bool
    ref: str
    extra: Any

def bool_schema(
    strict: bool | None = None, ref: str | None = None
) -> BoolSchema:
    return dict_not_none(type='bool', strict=strict, ref=ref)

It should be possible to make this typing safe, but I don’t know how?

I’d be willing to change dict_not_none e.g. to take a dict as an argument if that can fix typing, or even remove the function and use a comprehension or similar if that would fix the problem.

(Currently I’m just returning setting the return type to Any which avoids errors but effectively removes type checking)

You’re returning a dict, right? Can you not just add a return annotation to say you are returning a dict? That’s got to be better than annotating it as Any.

Better still would be to annotate both the input and return as BoolSchema. Untested:

def dict_not_none(d: BoolSchema) -> BoolSchema:
    return {k: v for k, v in kwargs.items() if v is not None}

Note that I’m not using **kwargs any longer.

If this doesn’t work, please copy and paste the errors that your type checker give into your reply.

I’m afraid this won’t work for two reasons:

  1. The argument to dict_not_none won’t be a valid BoolSchema if (for example) ref=None - that’s the point of the function.
  2. dict_not_none is used in 39 places in that file - again that’s the point of dict_not_none - to remove redundancy, if there was one such function I would build the return object manually.