Hacker News new | past | comments | ask | show | jobs | submit login

TypeScript is an excellent language.



I've been using TS since it's .8 days, and love it - but I think it's stretching things to say that it's an excellent language. It's a pragmatic language that makes JavaScript (which is an awful language) tolerable.


No it's not. It has all JS flaws - it's just better than js and it's easy to use it with js. Otherwise Dart would win.


I don't see how Dart wins at anything, really.

It's an extremely conservative language, offering little to nothing interesting that would make anyone switch from other solutions.

The ecosystem doesn't help it either:

For the frontend, it's stuck in a middle ground where it requires a JS interop layer (unlike TS, where it's typings are just an extra) but doesn't offer anything significant like Elm, BuckleScript, F#, ClojureScript and so many other great languages do when it comes to expresiveness. It doesn't even have algebraic data types, something TS does.

For the backend, it competes against almost all the frontend languages (due to node or native) as well as the big boys with huge ecosystems, variety of paradigms and amazing performance.

For mobile it has Flutter, which competes with Xamarin, Kivy, Qt and other bring-your-own-widgets solutions (deal-breaker for some apps and teams). In this case, Flutter is something I wanted to try out since those other solutions left me wanting and so did React Native, but Dart being such a lackluster language completely put me off of it, now having to turn to native with Kotlin after all this time looking at (and somewhat helping develop) the x-plat ecosystem.

I don't doubt that Dart will remain healthy for a long time due to Google's investment in it, but honestly, even if Fuchsia ends up being Android's succesor and Flutter ends up as its graphical toolkit, I'd instantly start looking for languages targeting the Dart VM or native interop.


> "other solutions left me wanting and so did React Native"

Could you please give specific examples of where you felt RN let you down? (Also, did you use Expo or vanilla RN?)

Thanks


The three biggest issues I have with it are these:

1) Language. Elm has set the standard for web languages and after using it for a while, JS or many of the popular replacements such as TypeScript are plain insufficient when it comes to providing as many compile-time safety guarantees. Doesn't help that I'm getting into Idris and even Elm's shoes are starting to feel a little too tight.

There's a project to write Elm and target React Native, but it's still too immature and it makes the next two issues worse.

I've yet to look at RN development through a BuckleScript stack, so that may be an acceptable alternative (even if not as safe as Elm, but on par/better than Kotlin)... but won't help at all with the next point.

2) Requires very complex tooling. This complexity will rear its ugly head when doing anything slightly out of the ordinary. All solutions (including Expo) I've seen seem to suffer from that issue, just with different defaults and different amounts of work necessary for different tasks.

I am not oblivious to why this is, since RN is not only based around the JS ecosystem and all the insanity that comes with it, it also has to deal with being a fat abstraction over native rather than take the easy way out, rolling its own cross-plat rendering and give up native widgets.

3) While it has come a long, long way, performance on old Android devices is still not always as smooth as native. I'm not sure how much this can realistically be improved since the bottleneck is interop, and avoiding it or shifting work around between native and JS is just not something I want to worry about.

However, this third point has improved so much I'm ready to handwave it away if the former two weren't a thing.

Lastly, not an issue with React Native itself, but JetBrains absolutely has the intention to bite into iOS' territory with Kotlin Native... and assuming they can pull off a half-decent adaptation of Apple's APIs I'm betting they will be the ones to finally take the x-plat cake, which makes it hard for me to believe investing time and code into RN solutions is a better proposition than native.

Hope that was useful in some way. If I should clarify anything or I have any misconception about RN please let me know.


" offering little to nothing interesting that would make anyone switch from other solutions"

Huh ? Compared to JS - Dart seems like a heaven. Don't known Elm - but looking on syntax it seems it's not so easy to pick up as for someone with Java/C# background. It's true Dart is not another fancy lang - it's very pragmatic.


Compared to JS, yes. But it's not JS that Dart truly competes against, it's all the other compile-to-JS languages some of which I mentioned, and Dart simply can't beat their pragmatism and/or expresiveness.

Elm is deceptively easy since it has great docs, the best compiler errors in the entire industry (no exaggeration here) and skips all the voodoo incantations of pure functional programming favoring a familiar language instead. Took me a couple of days to start writing toy websites with it coming with no functional experience, and a week to be productive.

I'd suggest you take a look at some of the talks on Elm. This is a good one: https://www.youtube.com/watch?v=EDp6UmaA9CM

Anything by Richard Feldman is great, too.


I've been digging a bit into Dart as I've read through Fuchsia's docs and poking around with the source.

It looks like a great language, but I think it hasn't done well on the web because it has very poor interop capabilities with JavaScript and its ecosystem. I'll note that I haven't dug that deeply into Dart, so maybe there's some great resources I've simply missed so far.

TypeScript and Flow are both great options because they work completely with existing codebases. They can be adopted gradually and integrate well with the ecosystem.

Another language that looks promising is Reason [0]. It's still very young, but they seem to be working hard to create an awesome language with a great interop story. Check out their getting started [1] guide. Most of the info related their interop is in the BuckleScript User Manual [2].

[0] https://facebook.github.io/reason/index.html

[1] https://facebook.github.io/reason/gettingStarted.html#javasc...

[2] http://bucklescript.github.io/bucklescript/Manual.html


Like what? TypeScript is careful to avoid a lot of JS's footguns (implicits, undefineds, etc.)


TS has nice features to avoid js bombs but all JS 'bad code' is legit by definition (JS superset). TS is super nice compared to JS but it is NOT excellent Lang.


> all JS 'bad code' is legit by definition (JS superset)

That's not true. There's a lot of JS code out there that is certainly not legit in TS. Probably the shortest example is `1 === "a"` which produces a TypeError, but if you use TS at all you'll understand that a lot of bad patterns are made painful or impossible thanks to the strict type system.


== versus === and all the other weak typing wats, undefined type still exists in typescript, no integer type, UTF16 strings are the ones coming to my mind and I don't even program in JS/TS


I'm pretty sure all weak typing warts basically stem from equality checks with ==/===. If you use === all the time you'll never run into them.

TS has optionals so undefined is not an issue.

The rest is valid.


There are also some JavaScript functions like isNaN that also do type coercion and of course +. How is this handled in typescript?


In a word, "correctly". The result of an expression with + or isNaN() will be of whatever type the JS spec says it should be. This is one of the less frequently touted, but more useful aspects of TypeScript - the lib.d.ts file acts as a partner to explain to you how the built-in JS type system actually works without you having to memorize or look up everything in docs.


By optionals I assume you mean null and undefined types, not optionals in the Scala or Swift sense.


For == vs === use a linter, same as you would for warts in other languages.

What's the issue with undefined - is it that you would use null instead?

I don't feel a need for integer type, but maybe that's because I grew up on JS. Integers feel like warts to me in a lot of cases, ie why would 2/3 == 1?


2/3 === .666666666666666629659232512495 is probably worse, because it can seduce you into thinking it's accurate. Why is `2 / 3 * 3 === 3`, but `1 / 3 * 3 < 3`?

JS's floating-point-or-bust, combined with some weird Math semantics, makes it challenging to write numerically correct functions.


That's a fair point. Which language do you think does it better, or is there a library you like to use (eg. Haskell's scientific type)?


Floating point tends to break all sorts of assumptions. For languages without static types, bignum integers and distinct operators for truncating vs FP division is probably best. This is how Python 3 works, plus Haskell and SML (with static types).


TypeScript addresses many of JavaScript's type-related issues but retains other JavaScript insanity: bizarre array semantics, Unicode ignorance, no integer arithmetic, regex facepalms, Math weirdness, etc.


What do you mean by bizarre array semantics? Genuinely curious.


Oh man, how much time do you have...

The root of the wtf is how Arrays play double-duty as both indexed and associative. The ES spec says that if you modify a property of an array object, the implementation must check if the (necessarily String) key changes after being round-tripped through a UInt32 conversion. If not, the key is a special array index that bumps the length; otherwise the length is unaffected.

    var arr1 = []; arr1[2147483648]=1; // arr1.length == 0
    var arr2 = []; arr2[2147483647]=1; // arr2.length == 2147483648
    var arr3 = []; arr3[-1]=1; // arr3.length == 0
Of course strings participate in this nonsense:

    var arr = []; arr["12345"] = 1; // arr.length == 123456
This is JavaScript so naturally .length is settable:

    var arr = []; arr.length = 3; // works!
But implementations are still required to distinguish between keys that are undefined and keys that outright don't exist:

   var arr = []; arr.length = 3;
   arr[0] = arr[2] = undefined;
   for (key in arr) print(key); // 0, 2
And of course you can set whatever random associative array property you like:

   var arr = []; arr[1] = true;
   arr[3.5] = false; // "works", .length is still 2
The intent is that array implementations may use efficient unboxed contiguous storage, but the spec requires that arrays may be sparse so it's still necessary to track which keys are actually set even if values are undefined.

Want to iterate an array's keys? There's no requirement that array indexes start at 0, and you may encounter random other keys from the array prototype.

TypedArrays are more limited/sane, thankfully.


Every time I see something like this, I stop and consider just how saner Lua is, even though in many ways it adopted similar approaches (e.g. associative arrays doubling as regular ones).


>32bit number indices not affecting length is crazy - I didn't know about that (I don't think I've knowingly dealt with an array that big).

TypeScript thankfully prevents all of these errors except for the one I mentioned.

Do you work on the spec or a JS implementation? That's some pretty impressive knowledge.


I have not implemented Array, but I know the poor soul who did!




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: