Yeah, there are some weird stuff in typescript, for instance, this typechecks
class Animal {}
class Dog extends Animal {
woof() {}
}
class Cat extends Animal {
meow() {}
}
let append_animals = (animals: Animal[], animal: Animal) => animals.push(animal)
let dogs = [new Dog()]
append_animals(dogs, new Cat())
dogs.map(dog => dog.woof())
Which if you evaluate, you'll obviously get:
Uncaught TypeError: dog.woof is not a function
Whereas Mypy won't typecheck the equivalent Python code:
class Animal:
pass
class Dog(Animal):
pass
def append_animals(animals: List[Animal], animal: Animal) -> None:
animals.append(animal)
dogs = [Dog()]
append_animals(dogs, Dog())
It'll throw with:
$ mypy types.py
types.py:16: error: Argument 1 to "append_animals" has incompatible type "List[Dog]"; expected "List[Animal]"
types.py:16: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
types.py:16: note: Consider using "Sequence" instead, which is covariant