I've been thinking about this one, and I think that it would be better to not make `TypeGuard` an instantiable type, instead having it be a special form that type checkers treat as `bool`. There's already some precedence for types that "don't really exist" here with `Literal`, where you wouldn't write `return Literal(2)`, but just `return 2`.
Firstly, I think this will make the functions read better. E.g.:
``` def is_two_element_tuple(val: Tuple[_T, ...]) -> TypeGuard[Tuple[_T, _T]]: return len(val) == 2
def is_string_list(val: List[object]) -> TypeGuard[List[str]]: return all(isinstance(x, str) for x in val) ```
Secondly (like `Literal`), not introducing a type here would mean that existing functions could be converted to type guards without modification. For example, there are a few functions in `inspect` that could be converted to type guards:
``` # Before def ismodule(object: object) -> bool: ... # After, maybe from types import ModuleType def ismodule(object: object) -> TypeGuard[ModuleType]: ... ```
If we required type guard functions to return an instance of `TypeGuard`, then no existing function could become a guard, because they will return `TypeGuard`'s parent type.