Initial thoughts from looking through
https://docs.python.org/3/library/typing.html#:
1. Love that it doesn't use structural typing, NewType seems great.
2. The syntax is bad. Maybe this is a "it just takes getting used to" thing, but I actually find it really bad. In TS, the syntax for typing almost always directly matches the syntax for the rest of the language. In Python, its a weird sort of LISPy DSL think that they made... compare:
Py: Callable[[List[Tuple[int, string]], Dict[string, string]], int]
TS: ([number, string][], { [key: string]: string }) => int
This only gets worse as you chain callables together, whereas in TS everything left-associates as you'd expect and it all works out nicely.
3. Admittedly, the TS dict syntax isn't beautiful, but it becomes very helpful for things like `{ [K in keyof T]: K extends number ? T[K] : never }`, which does not seem to be possible in Py.
4. Related to 3, but no never type? I see NoReturn, but it does not seem to actually cause any errors when you try to assign it to a variable. See below.
5. Type narrowing... does it exist? Seemingly not, see below.
6. Literals as types (enums)?
7. Generics, do I really need to pass in the internal representation of the type I'd like to use? That seems absurd. Will bad things happen if these internal identifiers collide? (Reference: `T = Generic('T')` creates a generic type)
Demo code that should throw an error at the assertUnreachable and nowhere else, but actually throws errors everywhere but the assert unreachable (types seemingly aren't narrowed by `type() == ...` checks):
def foo(x: Union[str, int, float]):
if (type(x) == int):
return x / 3
if (type(x) == str):
return x.upper()
return assertUnreachable()
def assertUnreachable() -> NoReturn:
raise RuntimeError('no way')
(this is all checked using mypy, v. 0.641)