I think that something in the proposal I sent was missed. The key of the proposal wasn't as much of "add a special value" (which it does), but mostly "use a Union[]" (I wrote it with the new | syntax, but I think this should be the same with explicit Union[Foo, Missing].
I stated this because the behaviour of "holes" in dictionaries already has Union semantics. Not just in the abstract sense of "there is more than one possible behaviour when evaluating mydict['mykey'] ", but in the general properties of Unions. For example consider this TypeDict declarations:
class A(TypedDict):
x: int
y: int|str
z: int|Missing
class B(TypedDict):
x: str
z: int
value: A|B
Currently the type of value["x"] is int|str (the union of the types for x in both types). What happens for "holes" then?
value["z"] has type int|Missing. That is the Union[int|Missing, int] which again are the types on both sides (note that we use here that Unions can be flattened and int|int == int). value["y"] is a bit more trickier, but we can consider that there's an implicit "y: Missing" in B (for every name except "x" and "z" ) so the type of value["y"] is int|str|Missing. value["doesnotexist"] has type Missing|Missing, which due to union rules, is equivalent to Missing.
Adding some special form like "Required[int|str]" will need to define what does it mean to have Union[Required[T1], T2] and similar interactions, and in the end you will end up recreating the definition and algebraic rules for a Union, because what we have conceptually here is a Union. I know some people have expressed their concern that these standalone values are unusual (but not unheard of, we already have NoReturn), but for me this emerges from the type system.
In fact, I think we might get away defining Missing as an alias for NoReturn, because right now I see no much of a semantic difference . For example, any code after value["foo"] should be ignored in the same way as code after sys.exit() (a function with result type NoReturn). Anyway, this is an extra idea and if I am wrong this paragraph can be ignored without affecting the previous argument
Hope the example drives the idea more clearly
Best,
D.