Disclaimer: I have not used MyPy. I'm just interested.
In the latter they don't enforce much, you just get a JS or regular Python file. (mypy is not a transpiler like TS, mostly because it explicitly wants to be able to target legacy JS runtimes - eg IE8 ES5 - whereas mypy needs a recent Python that supports type annotations)
There's a reason why strong static typeable code looks the way it looks (basically functional programming). You can type a monad chain, because it's a container type for arbitrary types interacting, but you can't easily type a switch nested in a for loop that uses a queue to walk a tree.
Of course the flip side is that to walk a tree functionally you need recursion schemas, and they are ugly/complex.
On the implementation side, I've found TypeScript's type inference to be far more capable. I've encountered several mypy bugs around type narrowing. The issues I've filed have greeted by a "yeah, this is a problem, but low priority since you can restructure your code to make it more explicit." I understand staffing is an issue for community projects, and the PSF is trying to do a lot with very little, but that doesn't change the fact that it's a deficiency when compared to other systems.
* it doesn't track the state of the variable. If I get a value thats Optional[int] there is no way to say 'if a is not None:' it will still complain that the variable could be none
* even with the mypy experimental TypedDict they're basically unusable IMO
* there is no 'keyof'
* there is no way to constrain to specific strings (or other primitives). I don't understand what literals are supposed to be but they aren't useful for usComing from typescript it's been very lackluster.
- TypedDict is an option but if you can, dataclasses work much better
- mypy does refine Optional[T] to T with an if check. Maybe you need to futz with the compiler options?
- Does Literal["foo"] not work? I've been using it with pydantic for de-serializing a tagged union of dicts and also for function args.
e.g.,
def call_to_service(api_type: Literal["users", "teams", "orgs") -> None: ...I think you're right, something must be mixed up. But then again this is the latest version of python and mypy, on intellij, so I'm not sure what I did wrong, it's using otherwise default options.
On point 1: def use_int(n: int): return n * 2
def foo(n: Optional[int]):
use_int(n) # MYPY complaints here because n could be None
if n is not None:
use_int(n) #MYPY allows this because it understood it cannot be None
2) TypeDict work fine, do you have an example of waht does not work
3) Of course, JS is different from Python, "keyof" doesn't make any sense in Python because Python uses class where JS uses dicts
4) Of course there is: Accepted = Literal["foo", "bar", 3]
def accept_values(v: Accepted):
print(v)
accept_values("foo")
accept_values("bar")
accept_values(3)
accept_values("wrong") # MYPY complains
accept_values(5) # MYPY complainsFrom the points you make it seem like you haven't really figured out how to use mypy...
TS and Python/Mypy are my daily drivers. I don't find the experience working with mypy any worse than working with TS. In fact I prefer composing and consuming types via dataclasses and NamedTuples over interfaces and TS classes.
type Animal =
{
type: "Dog"
dogtag: string
name: string
} | {
type: "Cat"
name: string
allowedOutside: boolean
}
function f(a: Animal) {
console.log(a.name) // always allowed
console.log(a.dogtag) // compile error
if(a.type === "Dog") {
console.log(a.dogtag) // Allowed
}
}
I believe Typescript is fairly unique in this capability. from typing import Union
class Dog:
dogtag: str
name: str
class Cat:
name: str
allowedOutside: bool
Animal = Union[Cat, Dog]
def do(a: Animal):
print(a.name) # Always allowed
print(a.dogtag) # MYPY error
if isinstance(a, Dog):
print(a.dogtag) # MYPY allowsBut the fact you have to import Union instead of using a pipe bothers me. It's useless boilerplate and verbose. So not o Python. I reported it, but Guido told me it will not happen.
And I have to agree with him. Just look at the mess sclalaz did/does with its use of clever pictogram-like symbol names.
Python is very much a language where newcomers are the norm. Make the source code at least a bit self-teaching seems like a good feature.
I'm sorry but "|" is not only a very commonly known operator in the entire programming world, it is already an officially supported operator by python, vastly used by the community for doing unions: sets use it, sqlalchemy use it, pandas use it.
Let's not confuse explicite and paperwork.
The Typescript docs have more details and advantages for this specific scenario: https://www.typescriptlang.org/docs/handbook/advanced-types....
Ref Link :- https://www.typescriptlang.org/docs/handbook/advanced-types....