Why TypeScript Isn't the Answer
walkercoderanger.com
walkercoderanger.com
While he makes some valid points. devs are using these languages because a lot of them just dont like javascript, and will never like it.
You cant design a language and expect every developper to agree on these choices, especially when it's the core language of a plateform (web).
So choice is good,nothing is perfect and javascript is far from perfect itself.
Coffeescript is productive and influenced ES6 heavily, Dart has its own ecosystem,Typescript fits people who want compile time type checking. And what language devs choose is nobody's business but theirs.
Front end devs are not interested in writing javascript,they are interested in using web apis and building products. At the end of the day,the user doesnt care about the language,but wether he can run the app in his browser or not.
It's funny the OP use Crockford citations, Coffeescript was an answer to Crockford's book at first place,and D. Crockford loves Coffeescript.
TypeScript CoffeeScript Dart ClojureScript
you got 3 out of the 4 so far
That being said, for the reasons I spelled out I think the current crop of options are really lacking. I get that developers are going to use whatever tool they have to get what they need done, but I don't see why we shouldn't provide them great tools to do their work in.
I'm interested in a source for your statement that "Crockford loves Coffeescript". What I found was http://zhan.renren.com/h5/entry/3602888497994246013 which while very favorable sounds more like my statement that it is good things like this are happening. He concludes "I'm not sure there's enough of a payoff there. But just as an experiment, as a design exercise, I think it's a brilliant piece of work."
That being said, for the reasons I spelled out
I think the current crop of options are really lacking.
then Lol, I can't address every single one one
You cant have it both ways.If I were the CTO of a Node-based startup with 10 or more developers, there's no way I'd allow the developers to choose whether they wanted to write their code in CoffeeScript, TypeScript, Dart, or clean JavaScript. Within a company there has to be at least some consistency.
http://faculty.salisbury.edu/~xswang/Research/Papers/SERelat...
Otherwise, TypeScript does solve specific problems and I like it.
However I strongly disagree with this, TypeScript isn't ment to 'Fix' JavaScript, as any valid JS is valid TS. This limits a lot.
What it does do, is reduce boiler plate, give you a take as much as you want level of typing. No features are missing, you can always just <any> and do what you want.
The 'flaw' that the Type Defintions for a library might change, and be out of date, is a also a massive con. Want to see if I've any simple type missing or changed errors introduced by an otherwise innocuous library change? Easy! Granted, it's no replacement for integration testing, to ensure functions still behave as expected.
The comment about the 'this' issue that plagues the functional mascarading as a class nature of JS, is incomplete. It is simple to fix in TS, using the Lambda notation.
http://icanmakethiswork.blogspot.co.uk/2014/04/typescript-in...
Whenever someone says "X isn't useful", you must add "in context Y". Someone for example, who says, they have no need of optional type checking, has never worked on a project like Gmail that has dozens of engineers and a million lines of code. Tools like Closure Compiler weren't made up because the JS programmers on the project love type checking, the introduction of a compiler obviously slows down workflow, they evolved over time as a necessity.
But Closure Compiler is completely unnecessary if you are a single engineer working on a small project that maybe has a thousand lines of progressively enhanced JS.
There is no ideal language for all scenarios.
The article fails to focus on the real issues and pain points of web development which really have nothing to do with the language use, and that is the pitfalls of the layout and rendering engine. Frankly, the language issues are a distraction to the real issues facing Web development today.
And just to comment on the GWT/Dart article, since I actually work on GWT, the idea of a 'major player' in Web development is fraught with bias. Again, context is important. As of last count, we have 130,000 monthly active GWT developers that we can count (there may be uncounted users of the SDK who get the libs through Maven central. I just keynoted the GWT.create conference recently, that was standing room only, major Banks, Financial Institutions, Health insurance companies, Nike, Amazon, even Apple iAds, use GWT internally for Web development.
The intense competition in the Web market means it is deeply fragmented with many solutions, and there will never be a winner-takes-all major player in either frameworks, or languages. Just like it never happened with Web 1.0 frameworks with Java. We had JSP/JSF, Wicket, Tapestry, Play, RIFE, the list of frameworks is just too long to name.
We live in a polyglot world and people should stop obsessing over whether their favorite language or framework "wins". Just get your work done and be happy.
We are building a web app platform for the jvm called HiveMind (crudzilla.com) and a major design choice we've made is to be very focused on web development. No single platform,framework,IDE need to magically be great for all problems.
Hi. As a user of TypeScript in all of my projects, if I find a typing bug or a deficiency in a typing, I commit a fix to DefinitelyTyped. Or if a library isn't typed, I create a typing myself and contribute it.
> Or, what if there are type definitions, but not for the particular version of the library you need to use?
Then you don't use type definitions, and you "fall back" to untyped interactions with the library -- just like JavaScript. Or, you write those type definitions yourself, and contribute them to DefinitelyTyped. They are very open to PRs.
> How can you be sure the definitions are correct?
You usually figure that out through testing, and you either contribute fixes upstream, use casting as a hackfix, or cease to use the typing. They are never going to be perfect, but they are a hell of a lot better than nothing.
And all definitions are required to have valid code associated with them that compiles properly. Usually this is grabbed from documentation, if available. Thus, it's likely that if a typing is broken, it's in a small subtle way that won't be encountered in common use-cases.
> If you love JavaScript, warts and all, but wish it had classes, modules, interfaces and static typing then TypeScript is the answer.
I hate JavaScript. But it's all we have to work with in the browser environment, and there are many wonderful libraries available that I like to use in my projects. So, I program in it.
TypeScript makes it much easier to write large projects with multiple contributors, and it makes it much easier for new contributors to have confidence in their changes, as a whole class of JavaScript runtime errors are automatically found by the compiler through type inference/type checking. And the Visual Studio tooling is just dandy, with up-and-coming support in Eclipse and WebStorm/IntelliJ.
TypeScript is the answer for me.
It seems excessively defensive to tell people who express a desire for better solutions to get out of the industry. If everybody accepts bad tools out of learned helplessness then there is no impetus to make things better.
"TypeScript is not the answer. Or perhaps it’s more accurate to say it is the answer to a different problem."
And I think that's a valid point. TypeScript is an answer to the problem of developing and maintaining a large body of JavaScript code. JavaScript alone is pretty good for small scripting tasks and TypeScript is similarly too much overhead for small tasks.
But TypeScript does nothing to fix the "JavaScript minefield" which is what the author thinks needs to be solved.
When I see a phrase like this, I wonder whether the author have every worked in a project with at least 100KLOC.
You can also reduce the "JavaScript mines" by using a linter. TSLint has a nice collection of lint rules (and you can write more of them yourself) to make it impossible to use .e.g "==" instead of "===".
"...we need something better. I hope to share some thoughts soon on what such a solution might look like. However, based on feedback in the comments, we’ll need to discuss JavaScript linters first."
"Realistically, the issues I have raised with CoffeeScript don’t come up every day. Ultimately though, they are enough to say we need something better. I hope to share some thoughts soon on what such a solution might look like. However, based on feedback in the comments, we’ll need to discuss JavaScript linters first."
Things aren't perfect. We get it. So suggest something better.
The author starts from the premise that static typing is bad and then concludes that typescript isn't the answe. The coffeescript article was better, this was pretty silly. I'd love to see his reviews of scala and Haskell..
I actually really like Haskell though I have never had the chance to do a project in it. I appreciate the strong type inference and its flexibility in static typing. I occasionally find myself frustrated my C#'s limitations around complex typing. Like that there is nothing close to existential types and you can't create more complex generic type constraints.
Scala seems cool in what little I have read about it. I really respect Martin Odersky who designed it. I'd like to learn more about it, until I do I can't speak much to it.
> The problem with JavaScript is not that it is a dynamically typed prototype based object-oriented language without classes. That is actually JavaScript’s strength.
the above suggests disliking static typing as a premise.
At dox (http://www.usedox.com) our stack is basically haskell/yesod in back typescript/angular up front. sure there are annoying limitations of typescript relative to haskell but compared to any of the AltJSs that we've looked at or used (coffee script, elm, fay, roy, purescript, dart, actual javascript) it has far and away the best combination of safety and ease of integration with javascript libraries.
We love coffee script's syntax but the type safety of TS has become a must-have that we can't live without.
Typescript, once you start adding annotations, does actually combat some of the bigger warts in JS. specifically erroring on wat-ops like 1 + "" vs 1 - "" or [] - "".
Also, I love the intellisense provided by VS through type definitions which also means less time spent on checking API docs, so far I've had very few problems with wrong or lacking type definitions for libs.
But it's not all about types. From what I've read from TS devs, they are trying to implement all ECMAScript 6 in TS so that basically (among other things) it gives you the javascript of tomorrow, today.
With their Open source nature, structural typing, open-ended interfaces, etc... I really thing they have made a perfect shot to capture JavaScript patterns statically.
I haven't found big issues with declaration files mismatches , and you can always ignore them declaring a variable of type any, but it's true that DefinitelyTyped repository is a mess and should be split.
The author fails to acknowledge any of the good consequences of typescript. Adding static typing, classes, modules, enums, shorter anonymous method syntax, default arguments, etc. etc. make a world of difference for writing clean, structured code that is rid of a whole class of bugs at compile time. It's simpler to read, easier to write, and more likely to be correct in typescript. And the intellisense in Visual Studio is phenomenal. Contrary to what he says, I think typescript does tackle head on the biggest problems of javascript and makes massive improvements.
Regarding type definitions, I've never had problems getting correct type definitions for all the libraries I use, and it's also always possible to just not use type definitions as a backup. He forgets to mention how great it is to be able to use any javascript library straight up (unlike most compile-to-javascript languages) -- and that in 99% of the cases there are existing type definitions which add on static types to regular javascript.
That's right, in perhaps one of the most brilliant features, typescript lets you add types after the fact to any javascript library, and it works well. Thus, IMHO, most javascript libraries are actually better in typescript!
Though typescript doesn't fix every problem (like the mechanics of what "this" refers to, although it helps here too), you almost don't want it to fix these, because only this way can you use regular javascript and its vast libraries so simply.
Typescript has always been a sort of compromise between making a better statically typed language and retaining a javascript core for compatibility, but this balance is executed so well that you just about have the best of both worlds.
* everything in a single repository on GitHub. Makes it hard, for instance, to reuse from other package managers, like Bower
* they don't have a good story around versioning different libraries. Last I checked, they had a typescript wrapper for jQuery, based on the latest version. Sticking with an older version? No accurate type definitions for you!Nobody forces you to stay up-to-date with the DefinitelyTyped repository. If you want definitions for version X, look at the definitions that were recent shortly after version X was released. Not completely effortless, but also not a structural, deal-breaking problem like you said.
install-package jQuery --version 2.0
We haven't had major problems with DT, but I see that over time this is crying out for a fix
Also, how will the Definitely Type project be able to handle a fix to the definitions of an old version that doesn't apply to the current version?
Like jstclair I appreciate their hard work, but I think they really need to change their approach soon to avoid a lot of pain down the road.
I can see that library versioning would be annoying but I think its more of a ecossystem problem then a technical one.
And if you need this newer versions today, this is what I think of a good approach:
Traceur is a JavaScript.next-to-JavaScript-of-today compiler
https://github.com/google/traceur-compiler(thanks @WalkerCodeRanger from reddit to link me here: it seems I'm the only DT org member who is active on reddit and now hackernews.. shit is about to get real :)
I'll do some representin', but keep in mind this is just my personal view as active member and not some sort of 'official' statement (let's be clear there).
--
DT and this type-definition effort is actually a pretty complex with some interesting aspects:
Org:
DefinitelyTyped has mostly grown organically from just one guy starting to share his definitions (borisyankov), then some others joined in (diullei) and then it just grew and grew and we now have > 380 definitions.
The org members are just enthusiast pitching in some time, with like 10 active members handling the PR's and a huge flock of random people sending in files and fixes. It is a mildly chaotic, best effort kind of thing. We have no hard ties to the TypeScript team, although we harass them mercilessly in the typescript-compiler repos with bug reports and feature requests. They are fully aware of DT, they link us and AFAIK they run our test suite with their new compiler versions.
Contribs:
Some definitions are really well maintained and much used; especially jquery and the angularjs defs are very popular, together with mocha/chai/sinon, underscore/lodash, jasmine etc. Others are less active: some have never been touched after a 16 year old enthusiast pushed his proud work for some niche module to us. This is no different then any package manager.
It is all welcome too, because work done is work done: next time somebody might pick up on it and improve, send it back, rinse, repeat.
Keep in mind it can be quite a time-intensive process to write the initial defintion file (and its test): it is easily a few hours burned, likely more for the bigger libraries. Not many people create new ones as it can be a slog sometimes (I actually like to do it: you learn buckets about the library you're modelling, so ask me anything about bluebird, lazy.js or highland API :)
There are some tools available out-there to automate extractiob: some export from JSDoc, C#, or other crazy solutions that cost as much work to use as they save, but even then it is a lot of hassle to do right.
In an ideal world the definitions would be maintained by the library authors, but alas many do not care for TypeScript (or Dart or whatever). Although some authors actively send in updates, mostly it are enthusiasts contributing what they can. Some are JavaScript/node open source veterans (on vim/sublime /webstorm/eclipse), while many other come from the MicroSoft Visual Studio / C# crowd. For many this is their first time using git and github or their first PR ever.
This then means that quality is very varied: we do have some quality rules and a contribution guide and try to be strict but is only as good as people can be pushed without bailing out (again, similar to any package repo). We have a testing procedure (running on Travis) and are actively working on improvements, but again, it is all loosely organised spare-time work with imperfect data.
Consumers:
There are a few main consumers of the repository:
- our NuGet exporter is a PowerShell script that bundles each directory and pushes that as NuGet packages. There are some improvements planned but we need some other things first (who has time? :) - TSD is a dedicated client (command-line and module). This is my main side project, previously by another org member. I'm actively developing this to cover many of the issues we see (it supports stuff like retrieving definitions for semver versions). This v0.5.x was a full re-imagining of a simpler version by @diullei, and v0.6.x is in the works (cleaner data model, betetr code style, more best-practices, more externalised functionality to re-use) - JetBrains IntelliJ (WebStorm etc) also reads from the Github repos: you can use it to augment auto-suggestion (even for plain JS files!) - Some other experimental clients (TPM) - And many people just use a git clone or manually grab definitions.
Version matching:
I see a lot of comments about how to get the correct definition for a particular library version. The repository (and our rules) already facilitate this: you can postfix a semver to the filename. For example: https://github.com/borisyankov/DefinitelyTyped/tree/master/n...
- TSD parses this and can filter it with semver ranges.
- The NuGet exporter currently does not do anything for this; it just bundles everything from each directory and pushes it to NuGet. We have a notion to improve the NuGet exporter to smarter package and annotate versions and other meta data, but we need a few other things before that (some of which I have in TSD but am now extracting to external modules).
But even then, in practice, nobody is creating or maintaining these older versions!
This is odd: for many critics it is a big deal, but for active users comes up only occasionally (it is after all a valid concern). It is mentioned in the contribution guide but almost nobody sends them in. If you'd need one you can look in the commit history and try to find one, then add it with the semver postfix. But then you need to backport any relevant fixes, and you never really know how perfect a definition is at any point in its history. Usually there are imperfections: that is just the nature of how it works with manual descriptions and of course the TypeScript type system can not describe everything.
Future:
We're brooding on a meta-data feature (a small yaml) that describes some properties for each definition, like if it can be found on npm, bower, if it has external module declaration etc. I need this for TSD, and NuGet could use it too. The requirements are a bit vague around the edges and we're weary to commit to something unmaintainable.
Bower / component.io:
It comes up time-and-time again that we should export these to bower. I think this is not a good idea at all:
The problem with bower is that every package needs it's own repository. This would mean that at the current count we'd maintain ~400 repositories, with likely more to come. This is not a lot of fun to maintain. Besides that github will be happy there is the real problem of how we'd ever going to test interdependent type definitions (yes, this is done a lot).
Then there is the thing with the git tags: bower identifies packages by a git tag with a semver. If you give a definition repos tags with semvers of the library it is modelling then it will be very unpleasant to back-port API fixes (as you'd have to update all the tags), or abandon the old ones which kinda defeats the purpose.
We can automate some of this of course, but that brings complexity, risk etc. Some users have started a test on this (dt-bower), but AFAIK it didn't work out (as I'd expect). If you look in the DT's issues and the codeplex forum you'll find plenty of talk about it (lots by me too).
Conclusion:
So yea, it is all a bit messy and organic, but it is very difficult to formalise. As long as libraries authors don't export type information by themselves it will have to be retrofitted by the community, which means human labour which means things get a little messy and less precise. But as we pool effort we all build on each other.
Is this bad?
That depends on what you expect out of it. It seems some of you expect C# level of perfect typing. TypeScript is not C#, TypeScript is power-boosted JavaScript.
You start with what you like about dynamic JavaScript, then add typing and compiler features where possible.
Fact is that even with all the imperfect type definitions this is way more exact then whatever you can do in Vanilla JS and your human meatbrain: instead of trying to remember every detail of the API from the documentation, we now describe it in definition files and have the compiler track it for us. Then we share this information, so other devs can benefit and need to spend less time in API docs themselves. And just like memories these get outdated, then you get back in the doc and update your knowledge (except with DT you can now share your enlightenment).
And don't forget Typescript works fine with definitions: you can do all the dynamic coding you want (implicit, or explicit with the 'any' data-type). Only add typing if you want a little more safety:
I personally use many modules from npm without typing them (I still do lots of regular JavaScript too btw). Before all this I did a lot of ActionScript (1, 2 and 3) and that also hits this sweetspot of dynamic and static in one language (but without the glory of npm).
And to be honest this is a bit of a #firstworldproblem:
IMHO one of the most amazing things in tech is this ongoing explosion of the JavaScript ecosystem: it was fun before, but node + npm made it go apeshit critical. I was all over that before TypeScript came along, and here we have this technology that is a clean, tight super-set that smoothly improves the original with that little bit of extra sanity and syntax power. It is not just a thing on its own but the way it meshes with the whole ecosystem that makes it pop. Dart has nothing on this. I will say nothing about CoffeeScript although it has it's place.
My penny (it got out of hand.. deal with it :)
My only experience using DT was through Nuget so I didn't realize you had the semver postfix. I suspect that like me most .NET devs will go to Nuget first, so I personally would place a high priority on getting semver in Nuget, but I understand that there are lots of other important things too.
My suggestion would to make including a semver part of your quality requirements so that at least you have a record of what version they were working against when they made the type definitions.
I hadn't realized the interdependent library testing/validation. You really are in a pickle about git branching/tagging and not being able to have separate repos. Problem is, the side by side definitions for different versions makes it difficult to merge fixes across versions (as compared to say a different branch for each version of the library). I think this is something that needs to be thought about long and hard. Could you use git submodules or subtrees to do what you need? Perhaps have each library in its own repo but then have a repo that pulls them together and has the interdependecy testing? That way most contributors could work in the repo for the project they care about and only a few contributors would worry about the combined one?
Thanks for sharing your experience with TypeScript and what is good about it. It's just not possible for me to address everything bad & good about a language in one blog post, so I have to focus on what's relevant to the point I am trying to make (in this case why I don't personally think TypeScript is the answer to JavaScript).
I absolutely agree that meshing with the JS ecosystem is of critical importance and Dart just doesn't have that the way TypeScript or CoffeeScript does.
We simply have a harder problem to solve than TypeScript (different features and semantics, working with the VM as well as compiling to JavaScript), so it's taking longer, but we're aiming for nothing short of awesome and seamless interop.
We already have dart:js, a low-level JS-interop library that works in dart2js and with the Dart VM. Admittedly it's a bit cumbersome for developers to use, but it provides the building blocks that we can use to make TypeScript-like Dart interfaces for JavaScript libraries, and to export Dart libraries to JavaScript.
It's great to hear about a project like DefinitelyTyped, because once we have the support in place, we're going to need something very much like it in Dart.
Stop wasting yours and others' time writing and reading these kinds of blog posts and concentrate on actually building something worthwhile.
I also want to gauge interest in creating another alternative to see whether it would be worth my time and effort.
As long as language designers persist in making unnecessary and unfortunate errors in their designs, we need to point these out.