class C< \
T, \
S, \
>(...):
...
Of the Eric's proposed ways of expressing type aliases, only the idea with a new keyword seems practical to me if we use square brackets. This is the first alternative that Eric mentioned:
ListOrDict<T1, T2> = List<T2> | Dict<T1, T2>
If we'd use square brackets instead, this would be syntactically identical to an indexed assignment, which wouldn't define the type alias, T1 or T2, and thus wouldn't work at runtime:
ListOrDict[T1, T2] = List[T2] | Dict[T1, T2]
The second idea is similarly ambiguous and looks like a regular generic type annotation when using square brackets, unless TypeAlias is a keyword. Again, T1 and T2 won't be defined at runtime:
ListOrDict: TypeAlias[T1, T2] = List[T2] | Dict[T1, T2]
The third idea has the same issue if using square brackets -- it already has different meaning currently and doesn't define T1 or T2:
ListOrDict: TypeAlias = type_alias[T1, T2](List[T2] | Dict[T1, T2])
If we introduce a new keyword (only treated as a keyword in this context), there would be no ambiguity and everything would work as expected, I think -- even with square brackets:
alias ListOrDict[T1, T2] = List[T2] | Dict[T1, T2]
Jukka