Live data from Hacker News

TypeScript’s quirks: How inconsistencies make the language more complex

blog.asana.com

111–120 of 216 posts

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#111
post #20

I still don't understand what pulls developers to Typescript. The examples given show major flaws in this (duck)type system. That it works when you don't use the 'any' type and when you know how to avoid all the edge cases and workarounds, I know. But when I see an example like this: const shasta = new Cat("Maine Coon") printDog(shasta) > Dog:Maine Coon I see a huge red flag. Coming from C/C++ it looks like a joke. W…

Why not embrace Elm or Purescript?

Because those are a massive paradigm shift. TS is easy. You can sell it as “JS but better. If all else fails you can always resort to any”. Selling Elm to someone who only ever used C# is very hard. I’ve tried.

It is also familiar enough for the hordes and horses of C# and Java devs in your company. It’s even an MS product. Enterprise yay!

A safe choice. You won’t be crucified if it goes wrong.

It’s sad, I know.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#112
post #91
post #77

Earlier quoted context omitted.

TypeScript’s goal isn’t to be sound. Its goal is to be a balance between type-safety and effort. Full type safety would require a lot of runtime checks injected into the final JavaScript, which TypeScript intentionally avoids. JavaScript will never be fully type-safe without fundamental changes, which will probably never happen.

"Full type safety would require a lot of runtime checks injected into the final JavaScript" Why would this be the case?

Array access is a good example.

Many type-safe languages throw an exception if you attempt to access an element in an array that is out of bounds but javascript just returns undefined.

Typescript ignores the fact that accessing an arbitrary element of an array could return undefined. If it did not ignore this fact then it would force you to deal with the potential undefined value retrieved from any array access (i.e you'd need to write a runtime check)

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#113
Let me be honest, but this article is just horrible. The whole article is for the sake of complaining (though I prefer to call this "nitpicking").

> 1. Interfaces with excess properties

... in immediate objects, which will never be reused. This is nothing worse than golang emitting errors on every single unused variable. There are good reasons to behaviours like this, even though not always preferable.

> 2. Classes (nominal typing)

It seems like the author straight rejects the idea of structural typing itself, by calling the concept itself a "quirk". This is rather about preference, not right-and-wrong. If this point is to be true, one should also reject duck typing, many other popular dynamic languages, a large portion of software industry, scientific researches, etc. Good luck with that.

> 3. Discriminated Unions

While I do agree that it's a shortfall of TS type system, the example is simply unrealistic. Using composite values as type discriminator is a bad design. Plus, the compiler is not even allowing anything destructive nor bug-prone.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#114

These can make sense if you think of TS as better-checked JavaScript, not as a from-scratch design for a statically typed language. Excess property checks catch a common JavaScript bug (typoed property names), structural static typing matches the dynamic duck typing JavaScript authors had already been working with (though I see how nominal would be useful), and it's awesome they found a workable hack for discriminate…

If you can pass a Cat to a Dog function, where is the better checking? That would be one of the hello-world test cases for a type checker bolted on to a dynamic language. That type checker itself has introduced the syntax for declaring Cat and Dog classes; yet is neglecting to do the obvious with it.

As a long time TypeScript user, I do think this is a design mistake with the language. For example, it breaks instanceof checks.

However:

- The language primarily uses structural typing. If two classes are compatible, it's not completely unreasonable to expect them to also behave in a structural way (though I would prefer them not to).

- Adding a private field to a class makes it work as a nominal type (https://michalzalecki.com/nominal-typing-in-typescript/#appr...). It feels a bit hacky and it's not very well documented, but you could argue that until a class has some private state you can't publicly access, there's no reason to prevent you from declaring a compatible class.

- From my experience idiomatic TypeScript rarely uses classes, the primary exception being React components. In teams I've been a part of we've always written TypeScript (and JavaScript) like an (impure) functional language, taking full advantage of ADTs, simple structurally typed data and more-or-less pure functions.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#115

These can make sense if you think of TS as better-checked JavaScript, not as a from-scratch design for a statically typed language. Excess property checks catch a common JavaScript bug (typoed property names), structural static typing matches the dynamic duck typing JavaScript authors had already been working with (though I see how nominal would be useful), and it's awesome they found a workable hack for discriminate…

If you can pass a Cat to a Dog function, where is the better checking? That would be one of the hello-world test cases for a type checker bolted on to a dynamic language. That type checker itself has introduced the syntax for declaring Cat and Dog classes; yet is neglecting to do the obvious with it.

> If you can pass a Cat to a Dog function, where is the better checking?

If you have compatible method, fields and types, in a duck-typed ecosystem like Javascript it is a major boon that it is possible to interchange them, because it happens all the time in the ecosystem.

The standard way to do enforce exactly the right interface in typescript if you need to is to add a `type: "cat" | "dog"` field to your Animal interface and have the Cat interface have `type: "cat"`. If works well and is very similar to a JVM Class object or .NET Type object.

Structural typing, literal types and dependant types are major blessings to have available sometimes, and I'd really like languages to adopt some of Typescripts power and simplicity in this. So far I've only seen Julia have some of it, although Scala 3 also introduces some bits.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#116

These can make sense if you think of TS as better-checked JavaScript, not as a from-scratch design for a statically typed language. Excess property checks catch a common JavaScript bug (typoed property names), structural static typing matches the dynamic duck typing JavaScript authors had already been working with (though I see how nominal would be useful), and it's awesome they found a workable hack for discriminate…

> TypeScript crew have managed to build something that can get traction where other efforts have not.

You mean Microsoft managed to get traction? It seems most TS proponents don't realize TS is a success because they fell for smart marketing and serious money behind the project, not because it's a better language than 'other efforts' like for example Purescript or Dart.

But every comment I make against TS seems futile. TS proponents defend their little language very fiercely regardless of all the flaws it has. It's almost worth a study how Microsoft managed to do that. Overall a real pity, because there are so many better options and ideas for those who want static typing. TS is actually the worse choice IMAO.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#117
This article makes me think about the "rust compile times are terrible" blog post from the other day.

If you spend a lot of time with a technology, day in and day out, you get intimately familiar with all of its shortcomings, and sometimes you maybe lose some perspective.

Having used Rust (enough to see its innovations and promise) and TypeScript (daily), I think they are incredible languages and platforms. Sure, they have shortcomings, but I think it's important to keep in perspective the huge advances in the state of the art they have brought us for these trade offs.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#118
post #113

Let me be honest, but this article is just horrible. The whole article is for the sake of complaining (though I prefer to call this "nitpicking"). > 1. Interfaces with excess properties ... in immediate objects, which will never be reused. This is nothing worse than golang emitting errors on every single unused variable. There are good reasons to behaviours like this, even though not always preferable. > 2. Classes (…

I don't want to go into detail, but everything the author said is true. These are real quirks, that aren't explained correctly in the documentation.

They are all justified, and the author acknowledges this, but nevertheless surprising.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#119

Earlier quoted context omitted.

If you can pass a Cat to a Dog function, where is the better checking? That would be one of the hello-world test cases for a type checker bolted on to a dynamic language. That type checker itself has introduced the syntax for declaring Cat and Dog classes; yet is neglecting to do the obvious with it.

Note that you can only pass Cat to a Dog function if: * All fields of Dog are also present in Cat, with compatible type signatures * All functions of Dog are also present in Cat, with comaptible type signatures "compatible type signatures" does seem to leave some suprising co/contravariance holes still when using wider union types, but C#/Java arrays also have co/contravariance holes and we don't automatically write…

C# has a great type system, but everything has ToString() and sometimes that doesn't output something sensible, and gets implicitly converted, leading to garbage.

Still much better than working in C or some other weakly typed languages.

Re: TypeScript’s quirks: How inconsistencies make the language more complex

#120
post #115

Earlier quoted context omitted.

If you can pass a Cat to a Dog function, where is the better checking? That would be one of the hello-world test cases for a type checker bolted on to a dynamic language. That type checker itself has introduced the syntax for declaring Cat and Dog classes; yet is neglecting to do the obvious with it.

> If you can pass a Cat to a Dog function, where is the better checking? If you have compatible method, fields and types, in a duck-typed ecosystem like Javascript it is a major boon that it is possible to interchange them, because it happens all the time in the ecosystem. The standard way to do enforce exactly the right interface in typescript if you need to is to add a `type: "cat" | "dog"` field to your Animal int…

Whatever words you use, it simply conflicts with basic JS and is a serious flaw.

  const cat = new Cat();
  if (cat instanceof Dog) console.log('this should never be possible!');

What is this strange protective behavior towards TS, can we stick to logic please?
Post reply on HN