4 ms·
I don't get TypeScript's type system. It is obviously very powerful and can model very complex type constraints. But then you have stuff like this where it is
by foepys 3y ago
I don't get TypeScript's type system.
It is obviously very powerful and can model very complex type constraints.
But then you have stuff like this where it is not checking types as I would expect:
interface Foo { bar: string; }
const f = {bar: "foobar"} as Readonly<Foo>;
function someFunc(): Foo {
return f; // No error or warning, even with all strict flags enabled
}
- sakesun 3y agoThis is an issue open for discussion since 2017 https://github.com/microsoft/TypeScript/issues/13347 https://github.com/microsoft/TypeScript/issues/13347
- rendall 3y agoSorry, I don't get it. What do you expect to happen here?
- PhilipRoman 3y agoPresumably the issue is that a Readonly<Foo> shouldn't be a subtype of Foo I should note that I haven't yet had the pleasure of using a language that handles const-ness properly, as Readonly<T> should be neither a subtype nor a supertype of T
- rendall 3y agoAs an aside, I'm on mobile and tried to visit the TypeScript playground to play around with this, but weirdly, the default code is an implementation of FizzBuzz! There was not an obvious way to clear it to get a blank editor. Even "select all" context menu was hijacked. So I gave up. I'll have to file an issue.
- eyelidlessness 3y agoWhat I do is delete all but a few characters after “code” in the URL, then reload to get an empty playground. It’s annoying but it works.
- LaGuardiaKid 3y agoHandling of readonly correctness is definitely something ts doesn't handle well
- globuous 3y agoYeah, 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
- Shacklz 3y agoFrom my point of view, this is one of those cases where structural typing just doesn't work all that well when used for OOP. Typescript does give you a solution to this problem, namely that you use generics to constrain the parameters of your method: let append_animals = <T extends Animal>(animals: T[], animal: T) => animals.push(animal) Your example now gives the expected error. TypeScript does indeed have its quirks, but most of them do not really matter for real-life purposes or can easily be worked around like in the example above.
- brabel 3y agoThe problem with your TS code is that it's using covariance on a mutable generic type, which is unsafe and strict type systems would've forbidden that. To expand: TS treats `Dog[]` as a subtype of `Animal[]` because `Dog` is a subtype of `Animal`... that work if you only read values from the array... but trying to change the array, you run into trouble. Some languages let you declare covariance (reading ) and contravariance explicitly to address this issue. To my limited knowledge of TS, that's not possible in TS (as it tries to keep things simple and compatible with JS, probably). The answers in this[1] SO question explain these concepts better than I could. [1] https://stackoverflow.com/questions/27414991/contravariance-vs-covariance-in-scala https://stackoverflow.com/questions/27414991/contravariance-...
- rektide 3y agoAre there other examples of ways TS confounds you? This feels like a "haha, gotcha!" moment. Like Gary Bernhardt's Wat talk, it's one single example that looks extremely silly... but has next to no actual impact on anyone using the language regularly, is like the faintest little quirk. Typescript seems reasonably acceptable. I struggle to think of what I would ask for, what would be significantly massively different in my life if there were a hypothetical much better alternative to Typescript.
- deathtrader666 3y ago>> if there were a hypothetical much better alternative to Typescript. Like ReScript ?
- foepys 3y agoDon't get me wrong, I am very glad that TS exists and I am using it at least weekly. But there are inconsistencies in the type system that are very surprising to beginners because TS is trying so hard to be good at edge cases.
- _fat_santa 3y agoHaving used TS in production with web and mobile (React Native) apps, most of it is rather simple interfaces to make sure you are passing data correctly. I'd say 99.9% of TS code I saw was to make sure that you passed SuperComplexBusinessObject correctly. But like you, I've come across many instances where I got "hey TS aren't you supposed throw an error here?"