
As a maintainer of pyright, I can say that implementing and maintaining support for a "Not Type" would be an immense amount of work within a static type checker. Assuming that all of the type rules could be worked out (and I'm skeptical of that — see below), it would require updating and expanding many parts of the type checking logic. The same is probably true for all of the runtime type checking libraries. I personally don't see enough value to justify the complexity this feature would add to the type system or the effort it would take to spec and resolve all of the issues. I can't think of any case where I've ever wanted this, and I don't find the provided examples all that compelling. It looks like the examples are also relying on some form of intersection type (an `&` operator), which presumably adds yet more complexity. Have you seen a construct like this in any other language? I'm not aware of any, but if you can find an example, it would be informative to look at how that language works through the many challenges this construct would add. If I understand the proposal correctly, a NotType would be equivalent to an "Any" except for the excluded type(s). That would be bad for strict type checking because most static type checking rules would be disabled for that symbol (as they are with "Any"). That means it would "blind" type checkers to many code errors. In general, we discourage people from using `Any` today for this reason. A NotType would also be bad for language server functionality like completion suggestions (Intellisense) because no completion suggestions can be offered for an "Any" type. If you pursue this idea, you'll need to work out all of the ways this feature intersects with existing type features. Here are a few off the top of my head: * What are the subtyping rules for types and NotTypes? * In what ways are Any and NotType equivalent, and in what ways are they not? * How does a NotType interact with generic classes? For example, what does `~list[T]` mean if `T` is used elsewhere in the same function signature? * How does a NotType interact with TypeVars? For example, what does ~T mean? * How does type narrowing work for NotType? * How does a union of a Type and a NotType work? * Can a TypeVar be bound to a NotType? What does that mean? * Can a NotType be used in an isinstance call? What does that mean? * Can a NotType be used as a type argument in a generic class? If so, how does it work with existing variance rules? * How should the TypeVar constraint solver handle the case where a TypeVar is being matched to both a type and a NotType? * How does NotType work with runtime type checking? The answers to many of these questions are not obvious to me. I predict it will take lots of effort (and likely debate) to work them out. I'm sure there are many other issues I'm forgetting. Discovering and resolving the full list of issues will likely require you to implement a full reference implementation in one of the existing type checkers as part of the spec'ing process. It's possible that the feature could be constrained in its use so it doesn't need to compose with all of these other type features, but a feature that is designed from the outset not to compose is probably not desirable. -Eric -- Eric Traut Contributor to Pylance and Pyright Microsoft