
It's unlikely that the type system will allow the creation of types from arbitrary (user-defined) function calls. There are a few special forms where this is allowed in the type system today, such as `NewType`, `TypeVar`, and `ParamSpec`, but these are very constrained in how they can be used.
There are several problems with supporting arbitrary user-defined function calls in type expressions. (By "type expression", I'm referring to an expression used in a type annotation or a type alias declarations.). 1. Evaluated types must be static, but you can pass variables to functions whose specific types are not known statically, and that can affect the return type. 2. It's important for evaluation of type expressions needs to be fast because they are used not only for type checking but also for language server features like completion suggestions. Complex expression evaluation can add tens or hundreds of milliseconds, which is not desirable for completions. 3. It's very important that evaluation of types in type expressions are deterministic across tools. This is possible for simple expression forms, but it is not guaranteed for call expressions. Different type checkers and language servers use subtly different rules and heuristics when applying overloads and solving for type variables.
There are similar issues with other complex expression forms (arithmetic operators, comparison operators, comprehensions, etc.), which is why these are also not allowed in type expressions. In most programming languages, type expressions use a different (simpler) grammar than value expressions. Python doesn't distinguish between these concepts at the grammar level, but type checkers do impose limits on the expression forms that are allowed for type expressions. And there are good reasons for this.
So, for all of these reasons, I think it would be a bad idea to allow function calls in type expressions.
In your example above, there is already a well-defined way in the type system to define a type alias that represents a union of two types:
```python UserOrError = User | Error ``` or better yet: ```python UserOrError: TypeAlias = User | Error ``` So there's no need to invent a new mechanism.
-- Eric Traut Contributor to Pylance & Pyright Microsoft