Hacker News new | comments | ask | show | jobs | submit login
Announcing TypeScript 3.0 (microsoft.com)
367 points by DanRosenwasser 6 months ago | hide | past | web | favorite | 179 comments

More and more projects are adding TypeScript definition files for us, and many are even being written (or rewritten) using TypeScript directly! I honestly think TypeScript is the future of JavaScript. In fact, I can't help but wonder what Microsoft's long term goal is with TS. They're making such blazingly fast progress with it, that I can't help but wonder if this is the "incubation" period of the language, and when it's finally "ready to hatch", they're going to do something big. Almost like this phase of TypeScript's life would traditionally be done inside MS privately, but they wanted to benefit from giving back to the community, from trust building within the community, and from being able to say "we provided the most advances to the JavaScript language out of any contributors by far" and somehow use that as leverage. Maybe they'll make an official TC39 proposal that TypeScript syntax be integrated into JavaScript, complete with a de facto free and open source implementation that browsers and Node.js are free to use to strip types live at compile-time. I just don't get it. They made VS Code, they bought Github, they made TypeScript... where are they going with this? I honestly wonder.

The tale of Typescript was that several of Microsoft's own JS codebases had gotten too huge to manage in just JS and Typescript was built to scratch their own itch first. Microsoft happened to have a smart developer-focused division that also realized that Microsoft's own customers could benefit from the tool, too.

Microsoft has invested quite heavily into some very large TS codebases: VS Code/Monaco, VSTS, the Azure portal, large components of Office, large components of Bing, and so forth. Given the scale of some of those projects (in terms of users at the very least, even before you get into metrics like lines of code or dollars generated), that is a lot of benefit to having a strong tool like Typescript to do that work in. Many of the same developers working in Typescript use C++ and/or C# daily, so they already understood the usefulness of things like static type checking. Releasing it to the public when they did seemed a very cogent realization that that "enterprise JS application problem" was far bigger than just Microsoft and they were in a good place to help with that, given it's long been a goal of the company to help developers.

As for a Typescript proposal for TC39, I'm willing to bet everyone is still worried about accidentally creating a second "ES4" debacle, including Microsoft. I'd love to see, and would much more expect at this point, a pragmatic compromise like Python's PEP 526 [0] / PEP 3107 [1] project, encouraging JS engines to syntactically accept things like Typescript's type annotations, but remaining agnostic to what the annotations represent semantically (giving other JS users the option of doing things with the annotations other than types, too, if they wished).

[0] https://www.python.org/dev/peps/pep-0526/ [1] https://www.python.org/dev/peps/pep-3107/

Even if JS engines were to accept the type annotation syntax, there would still be a need to strip out the types simply from the perspective of minimizing JavaScript bundle sizes.

Most Node code runs unminimized, and HTTP2 makes minimization less of a concern for the web. (It's still useful, of course, but less necessary.)

So sure it is likely that in many cases browsers will still mostly see JS with stripped annotations, but the reason to do it is the same as the debate over whether or not to strip comments and/or support sourcemaps. There's clear wins at the very least in debugging situations to allow unstripped type annotations all the way through to the dev tools. There are even cases where that may make sense even in a production environment, including things like metaprogramming if those annotations are reflectable.

This nice thing would be to have the option, whether or not most projects might still prefer to strip them out to optimize bundle sizes. As with almost all things, it's an interesting spectrum of tradeoffs.

How does HTTP2 make minimization less necessary?

There have been claims that http2 pipelining means it's more efficient to serve bundles as separate files, unminified so they can be downloaded in parallel. (I haven't yet seen numbers that show it's a benefit in practice though.)

Not just pipelining, but fewer more high-throughput connections, smaller HTTP header overhead, HTTP2 Push with the server being able to stream a "bundle equivalent" to the client in the background, and perhaps most importantly, Brotli compression which does pretty well with unminified JS.

Not necessarily, given that a binary representation is also being discussed (not to mix with WebAssembly).


> there would still be a need to strip out the types simply from the perspective of minimizing JavaScript bundle sizes.

Are you really sure?

To me that attitude sounds awfully close to cargo-culting.

How is that cargo-culting? GP's comment doesn't even seem to come close to the meaning of cargo-culting. And yes, type definitions in my projects account for a good percentage, anywhere from 5-25% of each file, if you take into account all the interfaces, parameter definitions, class types... So that's removing 5-25% of your minified JS bundle, and if we're talking a 4mb bundle, that could be 1mb of type information, completely useless at runtime. If you needed to map that type information to your source code, this is what source maps are for!

Microsoft wants "Developers, Developers, Developers!"

TypeScript makes JavaScript easier & less buggy IMO. The more people developing with TypeScript, the better chance they use Microsoft's other tools. Some of those tools cost money. Some also make deploying with Azure really easy & enjoyable. Azure is their big cash cow.

The more MS tools you use & the better perception of the company you have, the easier it is to find yourself just wanting to stay in their ecosystem.

That doesn't seem right. I don't know anyone who uses Azure outside of a .NET-centric programming job. Azure always seemed to be like "hey if you heard good things about AWS and need a place to deploy your code but you've never touched anything outside the Microsoft ecosystem, come try Azure!" I've seen it advertised on Stack Overflow a lot, but I have never even thought of looking into it, for the same reason I have no reason to install Visual Studio.

We primarily use Azure, and only 1 .NET legacy app lives there. Everything else is Python and JS! I'm enjoying Azure a lot!

Azure is aimed at Enterprises and developers inside those companies who already run a lot of Microsoft tech and are familiar with Visual Studio. They do really well in that space because they already have a lot of mind share there, and that is a very big opportunity for them monetarily in the next few years as a lot of Enterprises move to the cloud.

I suggest giving it a shot.

If you do Kubernetes type deployments they have some nice offerings for all levels of knowledge. They just released Service Fabric Mesh for those who know less about it.

If you just want a simple deployment, their App Services is really slick & easy with Github integration for JS, PHP, .NET & other stacks.

They also have some really good integrations with their serverless stuff that decreases the amount of code you have to write significantly.

Enterprise doesn't care about this. Enterprise cares about prices.

In my experience, enterprises care less about price & more about support, perceived reliability & how they calculate value. I typically see them pay through the nose for inferior products, that are over priced but offer support packages & are billed as an enterprise company. Ironically, the support usually leaves them frustrated as good support is hard to find.

battlegrounds uses azure

I see TS as basically the one example that has nothing to do with the MS ecosystem.

I actually only know web developers using Macs to edit their TS, maybe a rare case of Linux, zero other MS things used, except maybe VS Code. And maybe it's debatable if VS Code is the best TS editor, I also have no numbers about widespread use, but I doubt it's a majority.

I looked at a few surveys and nearly 50% of the developers are using Windows. I doubt that this can change so much for JavaScript.

Yeah, my data is anecdata - I only know one country and mostly small shops. But unless something drastically changed the last years where I was in startup land - many web developers tended to prefer Linux or Macs, whether they're using Rails, Python, or PHP. In general the bigger or more agency-like the company, the higher the percentage of Windows for developers.

It would be amazing if typescript could become the browser standard. I'm currently suffering from performance and readability issues from writing and filling typed structs in javascript with non-word alignment.

e.g. I've got data like this:

    struct Point{
    	float x, y, z;
    	unsigned char r, g, b;
    	unsigned short intensity;
    	double gps_time;

    Point[] points = new Point[1234];
Reading, generating, and manipulating data like this is a bitch in javascript. Typed arrays have to be aligned to the byte size of it's type and because the offset of gps_time isn't at a multiple of 8, it's not possible to read it with Float64Arrays. DataView works but it's an order of magnitude (!!) slower than typed arrays so the best thing I can do for now is to read a double by treating everything as Uint8Array(), and then read the 8 bytes of the double into a temporary ArrayBuffer that can be used to convert between types.

My hope is that Typescripts type system is good enough to be able to treat this kind of data similarely as you can in C++, and that it would then become standard.

Putting Typescript into the browser would make it very hard to evolve Typescript since we would have to wait for browser compatibility. Better to keep it in the compile toolchain.

It would be nice to have some more targeted solution for working with typed arrays, though.

Right. We will soon need TS to TS compilation as TS progresses way too fast for browser adoptions to catch up.

If everything is typed in TypeScript, I see a lot of serious potential for optimization, like using only the memory needed per object exactly like a struct in C or C++.

TypeScript isn't sound, so you can't rely on the types for optimization. The shape/hidden class optimization that JS engines already have is probably about as good as you can do.

The last soundness issue I'm aware of is the bivariant function issue which they resolved in 2.6

You can still do something like this:

    let x: number = "some string" as any;

That's sort of tautological. "Any" and type assertions are designed as the escape hatch of the type system. If you're trying to develop type safe typescript you obviously won't use those. The followup question is for typed code (excluding usage of any or type assertions) does typescript have an unsound type system? Afaik the answer is no.

In the real world you are forced to use "any" when the type definitions for a third-party library are not perfect.

This actually happens a lot with types from DefinitelyTyped that are not maintained by the original author of the library.

That would be the equivalent of static_cast in c++, or casting via (object) in C#. Both of those are considered type safe but can still be abused also.

I don't get it, I though the whole purpose of typescript is to prevent things like that?

You could still infer sound areas such as certain structs and patterns for using them. They could introduce sound mode or patterns for areas as well.

There is WebAssembly for that now.

I'm not a fan of WebAssembly. I like js because you can instantly reload and test changes to your code without lengthy build or compile times and I'm hoping for typescript to become standard so that the same applies for typescript. I doubt the same will ever be possible with WebAssembly.

Anything more complicated than a little jQuery stuff is going to need build tooling anyway, at least Webpack and probably JSLint and Mocha. Since those are already there, adding either Babel or TyepScript isn't all that difficult.

Just took .284s to re-compile a Rust (stdweb) app targeting WASM.

And well over 2 seconds for Webpack to deal with (just) bundling 6 JS files and the .wasm file.

what is lengthy to you? some languages can compile ~30k lines in 0.5 seconds

Anything > 1s

Curious, which languages compile that fast to WebAssembly?

Their strategy seems focused on increasing Azure market share.

This seems like the most logical. Growing azure meant MS had to pivot. They finally embraced Linux/open source because without them azure would be doomed.

I really hope they continue doing so and it's not just an attempt to take over a market then lock it down how they want. What's the term? Embrace, take over, discontinue?

Embrace, extend, extinguish :-)

Oh! Duh! How could I have forgotten Azure! Yes, that's definitely where all this is headed. They could be trying to position TypeScript as a secret weapon that gives Azure an edge over AWS. Especially if they're planning on using the type information, once it's universally near-100%, to build a blazingly fast platform using a new compiler and runtime that make use of TypeScript's unique features suited toward compiler optimizations. Especially considering Hejlsberg is behind TypeScript (see my other comment in this thread).

”we provided the most advances to the JavaScript language out of any contributors by far”

How do you figure that? As far as I am aware that honor goes to the CoffeeScript project, whether you hate it or love it, it's been the main inspirator for JavaScripts advances. And second to CoffeeScript would be all the little libraries that inspired JS's standard library expansions like JQuery and Underscore.

Do you really believe CoffeeScript's arrow functions (or whatever else) had a bigger impact than adding static types to JavaScript? CoffeeScript is mostly about shorter-syntax improvements, while TypeScript (or Flow) just changes everything… coding, debugging, refactoring, pushing code in prod with the assurance that it won't break…

Typescript is not a part of Javascript yet. Maybe I underestimate the marketshare of Typescript, but CoffeeScript has improved Javascript everywhere by being the inspirator for ES6.

And while I'd like to agree with you that having types in Javascript is more important than the coding comfort CoffeeScript brings, I still think ES6 was more important than Typescript is or will be. Before CoffeeScript coding in Javascript was at best annoying, and at worst absolutely terrible.

I wasn't aware of any advances to JS made by Coffescript, what advances has it made? Do you have examples?

You're right about jQuery and underscore, though I think jQuery's are often overstated (it and Sizzle inspired the querySelector API in browsers' DOM implementations, and not much else, underscore has had wide-ranging implications for ES6 in general)

As the other commenters said, the arrow functions, which are very comfortable and very directly inspired from CoffeeScript.

But more importantly, the whole idea of ES6 was inspired by CoffeeScript. This might seem weird if you were outside the loop at the time and don't realize how succesful it was, but the fact that ES6 got so many cool features was directly due to CoffeeScript's success.

If ES6 wouldn't have those features, people would not have switched from CoffeeScript back to pure Javascript. And the success of Typescript shows that they still have to move quickly to keep pure Javascript relevant.

Here's a list of comparisons between CoffeeScript and ES6/7:


Note that these are features that were not in ES5, then they were in CoffeeScript, and only then were they added to ES6. The similarities are in no way a coincidence, almost all of CoffeeScript was in one way or another integrated into ES6.

> the arrow functions, which are very comfortable and very directly inspired from CoffeeScript.

"Arrow functions" (lambdas) existed long before CoffeeScript. Arrows of varying types (usually => or ->) have been standard syntax for lambdas for easily decades. One of the language designers on the TS team was involved in a language that had lambdas a year before CoffeeScript came into existence. To call lambdas a CoffeeScript innovation is like calling actors an Elixir innovation.

On the subject of CoffeeScript inspiring ES, that is likely very true - at the very least it lit a fire under an extremely stale language. They carefully selected some very good ideas that worked well together and made a beautiful language with them. However impressive, beautiful language design is not innovation. Something like optional any is.

> "Arrow functions" (lambdas) existed long before CoffeeScript

I think the question was about whether they existed in the JavaScript community.

I'm sure much of Typescripts great features are not completely novel nor unique—e.g. generics come from c# and Java—but it is responsible for bringing them to JavaScript.

If CoffeeScript didn't have arrow functions, I don't think ES6 would have had arrow functions.

CoffeeScript had this mix of language features I think any language aficionado could have picked up at the time. It was just crazily succesful, no doubt due to its flawless execution by Jeremy Ashkenas.

I really haven't noticed any mark of its success on the German job market.

> the whole idea of ES6 was inspired by CoffeeScript. This might seem weird if you were outside the loop at the time and don't realize how succesful it was, but the fact that ES6 got so many cool features was directly due to CoffeeScript's success.

Not sure what "outside the loop" means here but do you have a source for this statement? I followed ES proposals quite closely throughout and wasn't aware of any such thing.

> Here's a list of comparisons between CoffeeScript and ES6/7:

> Note that these are features that were not in ES5, then they were in CoffeeScript, and only then were they added to ES6

Unless you supplied the wrong link, I think you're mistaken here. Of the many examples in the link, the majority are code that was in ES3, or—in the case of array methods—bare little resemblance to Coffescript (I think a lot of those were inspired by Underscore).

The exceptions are fat arrows and spread, and I think the latter has a more complex history.

Two other notables in that link: lexical scope was in JavaScript 1.7, introduced in Firefox 3.6, predating Coffescript's introduction. Generators had an early form in JavaScript 1.8 but the syntax changed for es6, and Coffescript adopted it after es6.

I supplied the right link. I suppose we're reading the page differently. If you don't think that page is evidence enough that CoffeeScript inspired much of ES6 then I suppose we experienced the times differently.

Here's a nice article showing that CoffeeScript was on Brendan's mind when he was working on Harmony (ES6): https://brendaneich.com/2010/11/paren-free/

He calls Ruby/Python/CoffeeScript "unsyntax" and he doesn't like it I think :P

edit: apparently he does like it, he just doesn't think it would work on the web, he elaborates here: http://intertwingly.net/blog/2010/11/25/Hobgoblin-of-Little-...

> I suppose we're reading the page differently. If you don't think that page is evidence enough...

The page is a list of examples of Coffescript done in Javascript. Whether they show evidence of Javascript taking features from Coffescript isn't really a subjective question; they do or they don't. I explicitly enumerated which do and which don't.

In terms of "experiencing the times differently", that is subjective, so I guess we did. One blog post from Eich on why he doesn't want to remove braces isn't really holistic, but you might be right in general.

Arrow functions, splats, default params, string interpolation, lexical scopes, classes, destructuring assignments, chained comparisons, for loops.

I'm not sure how you figure you enumerated which do and which don't. Apparently I'm preaching something unpopular, all my comments have been downvoted a bunch.

I don't think it is an either/or. TC39 has shown that they love multiple implementations of things. CoffeeScript and Typescript (and Babel) implementing things together ahead of the spec, and how they agreed/where they differed/what obstacles they encountered, was likely as much of a factor as either language in isolation.

Maybe it gave the sense that compiling JS was worth it than sticking with plain JS.

The fat arrow is the most obvious one that comes to mind.

I wasn't actually aware that was a Coffeescript first, I had the impression they started with -> and adopted fat arrows later with the advent of ES6, as I know fat arrows was in ES4, but you're right, Coffescript seems to predate even ES4. Good to know.

Probably arrow functions?

This feels exactly like coffeescript. At some point, it does seem like TS should simply outright fork javascript and go from there. That would at least remove most of my objections to the developer overhead.

What developer overhead? If you consider the compile-TypeScript phase to be literally no different than your jslint phase, then this build step doesn't really add any overhead. If you're talking about having to write out the types in your code, that's just a healthier alternative to everyone who ever reads or modifies your code having to keep that guess that type information and keep it all in their heads.

This is nothing like coffeescript.

Coffeescript was an entirely separate language that just happens to compile to Javascript. The whole fiasco with Coffeescript 1 -> 2 was that 1 only compiled to ES5 and couldn't support ES6+. Migrating to Coffeescript 2 is basically the same amount of work as migrating to modern day Javascript. You can't even write Javascript within a Coffeecript file without it breaking.

Typescript IS Javascript. You can copy paste code both ways and they'll still work.

I’m not a huge JavaScript developer as I prefer to code things in native languages wherever possible but TypeScript is amazing and has brought much-needed sanity to the world of interpreted scripting languages. With Hejlsberg at the helm it has gained some incredible type-related features that even traditional strongly-typed dynamically inferred languages haven’t been able to find elegant syntax for.

It started off taking language queues and inspirations from C# and other languages and is now at the point where they are the ones copying back. Impressive stuff, and it’s really come a long way since 1.0 which was so much more awkward to use.

I'm mainly a C# guy, and have never been a fan of JavaScript (although I concede it has improved dramatically over the last few years).

I've never liked front-end development, but my first Typescript project was something of a revelation for me - a familiar syntax, static types, async/await, automatic fields via some ctor sugar, and a great type system! I really like the way it blends aspects of C# with JavaScript and F# - if you didn't known it had Hejlsberg at the helm, you could easily guess.

I think you just solved the mystery I was wondering about... I bet Microsoft's endgame here is to create a new platform. Think about it, they're actually succeeding in getting types added to every single JS package out there, slowly but surely. Eventually, there'll be no more need for the `any` and `unknown` types, which I bet are just transitional. Once all JS in the world is completely and fully typed, they will have enough type information to create a blazingly fast alternative compiler and (minimal) runtime, even faster than C#, maybe even rivaling C or C++. I mean they literally put the guy who made C# in charge of TypeScript and had him working on this language for several years now. I have no idea how they'll avoid the same mistakes they made with UWP, but I honestly bet they're making a new platform even right now as we speak, and that they're going to unveil it in a year or two.

Aha! A new platform, brilliant! And better yet, it could be a common runtime, for different languages to inter-operate!

But what would they call it?!


Dot jNet.

Truly ignorant question here, what is a 'platform' in this context? (Or what could it be?)

A VM that replaces (or supersedes) JavaScript in the browser (and elsewhere).

I think one of the reasons typescript has been able to get so good so fast as by having types _not_ control execution. Traditional type systems have a whole lot of requirements that arise because of the need for types to offer the currency that drives the code generation (and optimization) processes.

I’m hoping the eventual way that typescript style typing helps with perf is by presenting new compilation modes that make it possible to detect at runtime places where the code executed (at runtime) might not be providing the performance that could be expected by the types (because of a lack of runtime deoptimization or lack of ability for runtime to specialize in the circumstances presented during the program’s execution).

I think that could be a pretty powerful way forward — and very pragmatic given that the vast majority of code in any code base doesn’t need to be particularly fast ... I think what’s needed in this domain are (1) powerful tools to help maintain correctness (2) a smooth way to find and fix performance issues where they occur — and ideally by being able to write those fixes in the same language. I think those more useful features for a web scale language than a language that bends over backward in terms of expressivity to make “everything fast” ...

Some believe that is the path of Web Assembly. That's still got a long ways to go though. In the meantime MS is working on compiling its languages to Web Assembly. It's most popular experiment is Blazor.

typo "language queues" — "language cues"

It is Anders Hejlsberg, who is in charge of both projects (or was in charge of C#) so the similarity is not that strange.

I have to say though that I like Typescript so much, precisely because it has such a great type system.

What does a "great type system" mean?

Being able to define the type of something with a lot of flexibility. Most languages only allow one kind of type. Typescript can have unions or types from intersections or extended types. It has an innovate set of type algebra inspired from different languages over time.

Not only that but once you have types for inputs, it can infer a lot of things. Augment the humans with almost magical code completion ability because it can reason using types and static code. It helps catch a whole bunch of issues in a dynamic language like Javascript.

I’d say Typescript makes javascript fun and scalable to use.

What does a great painting mean? It is hard to explain, you will have to go check it out on your own :)


The only thing that feels cheap here is your unnecessary contextual annotation without adding any proper value.

It's kind of crazy that Facebook has let TypeScript takes so much market share.

I've been using Flow for so long now. The techno is good, the integration with the code editors is good too, but Flow has a lot of small-but-really-annoying bugs (2235 issues on GitHub right now), the type definitions for third-party libs are meh (you often have to update/fix the definitions by yourself), the team seems extraordinarily unstaffed for such an important project, they don't share the roadmap at all, the priorities are clearly internal first (like improving the performances instead of fixing the bugs) and they don't seem to do much marketing or communication about it.

I wonder what's the future of Flow at this point.

And I'm seriously thinking to move to TS (for pro and personal projects) once create-react-app will work perfectly out-of-the-box with TS.

I tried Flow and TypeScript for the first time a few months ago. Flow is absolutely abandoned and dying. TypeScript is taking over where Flow left off, and is far ahead of the game by now. I use TypeScript with create-react-app in my client work and it is invaluable and a wonderful experience, with no downsides as far as I can see.

Once I heard about ReasonML I figured that was the end of Flow.

And re: create-react-app, have you tried react-scripts-ts? I've been using it all year with no real issues.

Honestly they're not even close. TS has been eating Flow's lunch pretty much all year. It won't be long now.

Interesting. I was considering Flow and was going to begin using it by sprinkling it in using their Comment Types[1]. I wanted something that I could use but also make it optional for the other devs. Only because I was just wanted to test it out and not fully commit to making the team use it right away.

[1] https://flow.org/en/docs/types/comments/

I'd love to still recommend Flow, and as I said the techno is good and does the job, and they continue to release new versions, but I just don't see what benefits you would get by choosing Flow over TS at this point. Flow and TS do exactly the same job, with almost the same syntax (with different ways to transform it in JS tho), but TS has a bigger community and MS seems to put more efforts/resources into it. This has been true for 1 or 2 years now, so…

Typescript also supports comment typing via JSDoc. I write complex types in a definition file and use them in JSDoc. Works great. https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-i...

Hold on, TS can typecheck your code just by using your jsdoc annotations?! That's a game changer for me!

Yes and it works quite well. Sometimes JSDoc fails to provide enough info about the types though.

I've been using TypeScript for a while, and one thing I keep wondering about is which polyfills are baked into the compiler. I don't know how I've been able to get this far without understanding it.

Turns out there are none. You have two compiler flags: Target and Lib. Lib determines the syntax and objects/apis you can use: ES2015, 2016, '17, etc, and Target determines which platform it will run on.

But as far as I can tell, setting target does nothing to materially change the output code. It doesn't polyfill. Rather it just causes additional configurations to feed into the Lib compiler argument.

How to Polyfill with Typescript: https://basarat.gitbooks.io/typescript/content/docs/types/li...

More on Target: https://basarat.gitbooks.io/typescript/content/docs/types/li...

Typescript does have built-in polyfills. See for yourself.

1. Goto http://www.typescriptlang.org/play/

2. Enter the code `function* gen() { yield "foo"; }`

3. Behold the mighty state machine in the compiled output.

Specifically, TS has polyfills for language features (eg iterators), not library features (eg `Array.prototype[Symbol.iterator]`).

Exactly what Arnavion said. So if you want to write es-latest with TypeScript but support es5 simply set your target to be es5, import core-js for API polyfills and set lib to your desired es version.

It does have polyfills, but precisely to avoid relying on those I tend to stick to using the same in and out language. Babel is a better translator, and typescript is good at doing types. Add sorcery.js to chain the source maps and you’re cooking with gas.

It sounds only to me that you create an much more complex and harder to debug build pipeline with little added benefit. Please explain what Babel makes a better translator.

In what way have you found Babel to be a better translator?

Support of features, maturity, etc. “Do one thing and do it well” applies.

Have a look at the Babel website. There are tons of plugins and features: generators, symbols, async generators , object spread (long before TS had it), .........

Then there is automatic tracking of what is supported by your runtime , e.g. you can say “use polyfills for anything not supported by the current version of node”.

.babelrc is a complex beast, because polyfilling is complex. Let Babel solve that, and focus your TS energy on typechecking.

You're actually arguing against your own point. "Do one thing and do it well" is a great philosophy, and TypeScript actually does that more than Babel does. Babel does translation and polyfill, TypeScript only does translation. Type checking is only done during the translation phase for both tools (using Flow for Babel). So I would say TypeScript is cleaner and simpler in that regard.

The improved error messages look very nice. Typescript can produce some rather large error messages, and picking out the relevant type mismatch instead of hitting the user with a wall of text is a vast improvement.

This is a great update! It often feels impossible to decipher the wall-of-text error messages in TypeScript.

If I'm going to "upgrade" from JavaScript, why would I specifically choose TypeScript?

Yes, it gives some compile-time-only type safety in certain places, but it doesn't provide state safety like ClojureScript. I'm more worried about state/reference-based bugs creeping into my code versus type related issues, which I'll be checking via unit tests anyway. On top of that, it doesn't protect you from the usual JavaScript pitfalls since it's backwards compatible, including the bad parts.

Or am I missing something here? Is it popular because it lets you directly upgrade existing JavaScript files? I can see that being a big draw. Small and gradual improvement, yeah?

There are various options for trading away backward compatibility to gain protection from the usual JS pitfalls. Search for "strict" on https://www.typescriptlang.org/docs/handbook/compiler-option...

What do you mean by "state safety" in ClojureScript?

For example, it couldn't mean atoms/CAS because it's already single-threaded.

Also, you'd consider upgrading to Typescript because static-typing was on your wishlist. ClojureScript isn't really a competitor.

In fact, I ultimately found that "I still want a dynamically-typed language but with some technical improvements" is the weakest reasoning for switching away from Javascript which is why I ended up dropping ClojureScript. Meanwhile I've found something like Elm goes far enough to make the switch more worthwhile (static typing, built-in front-end architecture, etc).

You left it too soon. Clojure.spec brings much more than most of the other type systems could deliver.

It's popular because OOP is the only thing most people know and understand better than any other paradigm and has been a staple of "reliable software" in big business.

TypeScript supports both FP and OOP styles of programming. And it doesn't add any new OOP features on top of JavaScript.

One might argue that interfaces are an OOP feature that TypeScript adds. That said, you aren't forced to use them.

Interfaces are excellent for defining structures in both FP and OOP paradigms in my opinion. They simply describe the shape of data. This is useful in most situations I can think of at compile time.

Am I the only one that thinks "function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R { return fn(...args); }" looks horrible?

I imagine most code bases will contain a very small number (probably zero) type definitions with a spread tuple type. There are only so many ways to solve being type safe in a language that is so permissive, and sometimes it causes the result to look ugly. Ideally 95% of end users will never need to type this, only rely on it.

"For this function named `call`, the first argument must be a function `fn`, and subsequent arguments must be the type of arguments that `fn` expects. The return value of `call` is the same type as the return value of `fn`."

How would you recommend communicating all that in an extended version of ECMAscript?

I like TypeScript's syntax, but I think the way function types are declared is ugly.

If you have a function from A to B, you have to declare its type as

    type MyFunction = (arg1: A) => B
instead of

    type MyFunction = A => B
Here's that syntax applied to the example from GP:

    function call<TS extends any[], R>(fn: (...args: TS) => R, ...args: TS): R { return fn(...args); }

    function call<TS extends any[], R>(fn: ...TS => R, ...args: TS): R { return fn(...args); }

The syntax is probably meant to differentiate between a function expression and a function type declaration.

Any notation you're not familiar with looks horrible.

It's a rather complex construct: A function that takes a function and a list of arguments that calls that function with those arguments.

This construct would actually be more complex if the parameter list types were actually specified instead of being any[].

Very clear for me. What's horrible about it?

It's hard to gauge its looks as unfamiliar with TS as I am but would the equivalent without the spread operator look any better?

I call code like this 'clever' as it uses the language constructs to get usually a very optimal end result at the behest of being harder for n00bs like myself to parse.

I do wonder what a prettier version of this would look like. It certainly wouldn't be this concise but would it be better or harder to follow? I'm okay with something like this if it solves a very specific problem I hardly see. If my entire code base is littered with this? No thanks. Yea eventually it'd be second nature but I'd rather it be more verbose and slightly easier to unpack than this tightly packed.

First of all: That is both the function definition and implementation on the same row! Make line breaks around the curly braces.

Secondly, the (...args: TS) => R can be extracted into another type/interface, this way you would just get "function call<TS extends any[], R>(fn: Callable<TS, R>, ...args: TS): R"

It should be formatted better, but other than that, I don't see the problem; yes it is hard to parse, but that is because a lot is going on.

Yes, it is aesthetically ugly. But as someone who has used TypeScript for a handful of months, it's very easy to read.

yes it seems a bit much at first glance, I hope the learning curve for beginners is not too steep.

“The question is not whether JavaScript is broken. The question is whether it is broken enough to merit being replaced by something else.” ~ Anders Hejlsberg

“Big JavaScript codebases tend to become read-only.” ~ Anders Hejlsberg

Anders Hejlsberg and Lars Bak: TypeScript, JavaScript, and Dart https://channel9.msdn.com/Shows/Going+Deep/Anders-Hejlsberg-...

It would be great if there was a way to use the type information from within the code, ie. without type erasure.

Often we find that we create a nice model in TS, only to handle a lot of switching on types in the runtime. This is sometimes a smell but sometimes unavoidable, unless type information can be present in the runtime.

That's probably unlikely to happen, as it falls out of line with the design goals of TS, but check out io-ts[0] for a library approach to this problem.

[0] https://github.com/gcanti/io-ts

Literally every release I check the notes, the roadmap, and the nearly 4 year old issue filed for runtime type information and every release I am disappointed.

All the TypeScript dependency injection libraries rely on decorators or something else requiring modifying the classes being injected.

It makes the code look terrible and this is really my only complaint about TypeScript which is otherwise fantastic. I basically only do DI by hand because of it.

I use ajv's schema-based validation at all entry points to my application (user input from forms, urls, whatever comes back from an API, etc) and find I can very safely assume all data after that point is totally safe, so I'm using TypeScript to ensure _I'm_ not doing anything stupid. Hopefully that makes sense. Runtime type checking would be neat for sure, but I'm mostly worried about the dumb things I'll do. It's not too hard to strictly and cleanly validate foreign data at runtime, but it's historically very easy to shoot yourself in the foot with JavaScript. So I'm very happy.

While I have already encountered scenarios where the "Extracting and spreading parameter lists with tuples" would have been helpful, this feels more like a duct-tape hack instead of properly tackling overloads. I can see arguments against TS doing that much magic, but the current situation when dealing with overloaded functions (which you can do just fine in vanilla JS) is also not really approachable.

Also, unknown is a great addition.

EDIT: Just checked out their roadmap and while not exactly what I had in mind, Variadic Kinds is there and way more interesting: https://github.com/Microsoft/TypeScript/issues/5453

I'm particularly excited about project references. We have quite a few small web apps that use the client/server/shared structure and the default Angular webpack configuration does not like relative references (i.e. referencing ../shared from client). I'm hoping this resolves the issue of having to install the shared project as a module or ejecting the webpack configuration.

We're working on converting EnvKey’s[1] babel/ES6 codebase to TypeScript. It has been a true pleasure so far and has already brought gains in safety and productivity. I've never worked with a type system that is so intuitive and so rarely violates the principle of least surprise. It's amazingly easy to pick up, and also easy to gradually introduce it to existing js code in an iterative fashion. Color me impressed!

A few questions for TS veterans:

- With babel, we used the module-resolver plugin to set a custom root for absolute imports. In TS, it seems relative imports (import x from '../../../i-hate-life') are the norm, which turns ugly fast. How are folks dealing with this? Or aren’t they?

- Our codebase uses Ramda heavily for FP, and it can be hard to get TS to play nicely sometimes. Any tips on how to most effectively do Ramda/FP in TS?

- Am I missing out by not switching to VSCode? I’m using ST3 currently and it works, but there’s no fancy intellisense. Are the benefits worth picking up a new editor for?

1 - https://www.envkey.com

> Am I missing out by not switching to VSCode? I’m using ST3 currently and it works, but there’s no fancy intellisense. Are the benefits worth picking up a new editor for?

Well... typescript comes with tsserver, which is a local language-server (a Typescript LSP-server), which is what VSCode uses to provide all that goodness.

If you find a LSP-plugin for your favorite editor, it should thereotically be able to offer the same.

For instance, Emacs has tide[1] which uses tsserver (just like VSCode) to provide the same functionality.

I’d be surprised if there were no LSP or tsserver-clients for ST3. No need to leave something you know well over a single feature it may actually support.

[1] https://github.com/ananthakumaran/tide

About module resolution, you are looking for "paths" compiler option :


The "paths" compiler option only instructs TypeScript where to find files for resolution, but doesn't automatically rewrite those path aliases to their correct locations after build. There are plugins for JS bundlers like Webpack and Rollup so that they too can understand the path aliases, but if you're just looking to run the build JavaScript with vanilla Node, I've found the following two projects useful:

- https://github.com/dividab/tsconfig-paths - resolves paths aliases at runtime in Node

- https://github.com/duffman/tspath - run after build, it rewrites the imports in the resulting JavaScript files

I've switched to VSCode after years of WebStorm, almost painlessly. I would advise to try it for 2/3 weeks (taking the time to configure it and install relevant plugins as you go), that should be enough to give you a sense of it's working you or not

Do you feel you miss anything from WebStorm?

The new Tuple improvements in Typescript 3 should help give Ramda the chance at much better type improvements soon, if a smart developer takes a crack at updating the definitions for it.

The tuple improvements should be quite exciting for many FP/FP-ish libraries in TS.

The best option right now for keeping relative imports clean is using the `paths` compiler option to create aliases. This works most of the time but in some cases typescript won't rewrite paths in the javascript output so modules can't be resolved at runtime, so you'll need to use webpack or another tool in your build script to rewrite them.

See: https://decembersoft.com/posts/say-goodbye-to-relative-paths...

If you're using webpack with ts-loader you can use https://www.npmjs.com/package/tsconfig-paths-webpack-plugin to create aliases in webpack. awesome-typescript-loader has the same functionality available too I believe

Cool, that looks like it could work for client-side code that gets run through webpack, but what about for a node-friendly library?

I use tsconfig's `paths` in combination with the `require-rewrite` npm module (https://github.com/IUnknown68/require-rewrite).

Here's an example:

    // tsconfig.json
    "paths": {
        "#src/*": ["src/*"],

    // package.json
    "requireRewrite": {
        "map": [
    // src/path1/x.ts
    import { X } from '#src/path2/y.ts`

> Am I missing out by not switching to VSCode?

I would say yes! VSCode also has many other things to offer over ST3 besides IntelliSense btw.

Yeah? Would you mind giving a quick overview?

The biggest three advantages I can think of right now:

* Git integration: You can directly edit in diffs, commit from the sidebar, see your submodules and commit in them, ...

* Integrated terminal which can also run tasks, so colors and input will work

* Much better debugging support (AFAIK ST3 has none out-of-the-box)

It's been a while since I've seriously used Sublime Text though.

Also framework plugins that leverage all of that, Vetur is a work of art.

Cool, thanks! I think I'll give it a shot.

I’ve reluctantly switched from st3 to vscode for all of my TS projects. the auto import feature makes dependency management... manageable (so may solve 1. for you too). i think the slightly slower UI is more than made up for with all kinds if nice autocompletes and powerful rename/refactoring capabilities.

for a functional library that plays nicely with TS check this out: https://github.com/gcanti/fp-ts

Looks interesting, but I get the feeling I need to have already downed a few gallons of Haskell kool-aid to understand this? Is there a beginner-friendly overview somewhere?

What's nice about Ramda is that while it uses the Haskell-ish vocabulary and type signatures in its docs, someone can also just dive in and start using it as if it were an underscore-like library and not worry about all the more cerebral stuff.

How well does Typescript play with existing node packages? Last I checked you need to do some work extra work (typings?) to get it working. That's the biggest reason I've not yet switched over to typescript.

Probably 90% of third party libraries I ever used in my TypeScript projects have TypeScript interfaces built into them, so you just install the package like normal `npm i -P somelib`, and TypeScript automatically knows its types. Maybe 9% of them don't, and you have to add types like `npm i -D @types/somelib`. And the other 1% you can add manually yourself by adding them into `global.d.ts` in your project and only creating types for the functions you actually use. I only ever had to do this once, and it took about an hour total. It would have been more like 5 minutes if I had known that you can use the `typeof` operator in TS to specify that a given field is a constructor of another type.

That's true, but typings exist for most of the common packages:

  npm i express @types/express
It usually "just works", but it really depends on how obscure the packages you're using are.

4,720 type definition files at the moment: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/mast...

A lot of packages have types built into them.

Others have types available in "@types/<package>".

For everything else, I create a "types.d.ts" file that just has a bunch of stuff like:

declare module 'twilio';

declare module 'bitly';

declare module 'cloudinary';

declare module 'tmp-promise';

declare module 'dialogflow';

declare module 'fuel-rest';

And then those modules get set to the "any" type.

It's not the best. I had to trawl through a bunch of documentation and filter out old info (modules became namespaces? I think?), and try different formats for the typings file. Tbh there should be a FAQ that is just: Help, the compiler is complaining about a package, how do I fix it? Also, why do I need to clone the DefinitelyTyped repo and make a PR to add a typing file? Why can't I just make an NPM package?

These are all nitpicks in light of the amazing achievement that is typechecking JavaScript. But I wouldn't mind a little more ergonomics for package typing.

It's hopefully getting easier. Many libraries increasingly just pack their own definitions, which really is the best case. `npm install package` and done.

Writing a temporary definition file to just make something work is as easy as a one-liner in most cases now (make a .d.ts file somewhere in your project and add: `declare module 'module-name'` and/or `declare module 'module-name/*'`, depending on how the module is supposed to be used).

> Also, why do I need to clone the DefinitelyTyped repo and make a PR to add a typing file? Why can't I just make an NPM package?

It is possible. DefinitelyTyped is a publishing infrastructure bottleneck for sure. But it's a useful infrastructure bottleneck in doing somewhat minimal gatekeeping of the `@types` namespace on NPM and keeping it from filling with garbage. (I was a somewhat vocal critic of it before NPM @types, but I've mellowed again on it, partly because it is shrinking slowly in some areas as more NPM libraries adopt types directly. Some of my favorite contributions are PRs to remove types in DT because a library added their own directly to their NPM packages.)

Though a baked-in default in Typescript, @types is only semi-magic. The configuration knob is called typeRoots [1]. You can't configure a recursive search path like `@types` with it, but you can use it for experimenting with non-DefinitelyTyped types packages. (DT itself uses typeRoots internally for all of its testing.)

[1] https://www.typescriptlang.org/docs/handbook/tsconfig-json.h...

It has support for external type definitions, which can be installed from NPM like any other package. These are only necessary for packages which don't support typescript themselves. But it can definitely be an issue for smaller, less well supported packages where you can be left with a choice of writing type definitions yourself or turning off type safety for that library (using the `any` type).

I don't see that as much of an issue though. You wouldn't get any type-checking if you weren't using TypeScript, so it's still a net gain even if a few packages are `any`.

If a package doesn't have a typing you just do `declare module "whatever";` in a global.d.ts file and you're all set, you can use it as you would in JavaScript (it's typed to any).

Hardly a problem at all.

You can use any regular JS library from typescript. You just won't get type checking in calls to it.

Looking forward to the day that TypeScript no longer needs to compile into JavaScript, and is natively supported by all major browsers.

A bit like Objective-C and C++ got free of their initial compilation model.

That would suck, because then we would be forever forced to use ancient versions, because 2% of our customers are on Windows 95.

A much better model would be a progressive enhancement, where we can deliver optional types that browsers can then use if they understand them. That way there will also be a reason to upgrade for users.

As much as I love the idea of letting the browser do some crazy optimization with native types -- I don't think it will ever happen. Or perhaps maybe it shouldn't happen.

The only reason TS is able to iterate so quickly is because of the compilation cycle. Without it, progress forward would probably come to a screeching halt.

Yup, with https://webassembly.org/

Not only TypeScript, one day we would be able to compile Haskell as well: https://github.com/WebGHC

I've been waiting for TypeScript to solve the problem of param destructuring, but surely this is not it?

Param destructuring is one of the absolute best features of ES2015. TypeScript breaks it.

Reading this page I can't actually tell if param destructuring is even being addressed but I can see alot of at first glance weird and obtuse looking code.

Not an obvious up front win.

Parameter destructuring works. `funcName({ param1, param2 }: { param1: number; param2: string; }) { ... }`

What problem? TypeScript has supported param destructuring for a while.

Can you give an example?

>So what have we done since? What, apart from new ECMAScript features like the long-await-ed async/await, generators, and object rest/spread brought us to TypeScript 3.0?

Wait, Typescript didn't have async/await and generators until this release???!!!

They're talking about all the releases they've done since 2.0. Await/async support was added in v2.1: https://github.com/Microsoft/TypeScript/wiki/Roadmap#21-dece...

It most certainly did, I've been using async/await in Typescript for well over a year. From memory, it arrived in something like v2.2?

These are JavaScript features, they're saying "what we've done apart from adding support for this"

I would like to thank the Javascript community for finally clearing up the whole "JS is not Java" debacle by just throwing in the towel and becoming Java, even if they call it Typescript now. JS sure is such a modern language, you can tell because its always changing. Time to go build me some applets, sorry, SPAs!

Still haven't even used Typescript. What's the draw?

Most people that care about Typescript are JavaScript developers who desire more structure and safety. It can't do anything that JavaScript itself can't do. The article itself has a great description of the benefits in the first paragraph.

I'm familiar with it and have used FlowType which I believe has similar qualities. Just didn't feel worth the effort if you're building for throwawayability. So I'm still left wondering what's the draw.

If you're familiar with it, you might want to consider sharing your thoughts on it rather having people waste their time explaining something to you that you're already familiar with. Otherwise, your inquiry doesn't come off as genuine.

> Just didn't feel worth the effort if you're building for throwawayability.

Now that's a legitimate point. If you're building for throwawayability, then TypeScript and FlowType are probably not worth your effort. For other people, modeling things with types helps them move faster even for throwawayability.

Personally, I tend to code first, use type inferencing first, and then annotate later. However, I also tend to use a lot of reflection as well to help me prototype things quicker. If I've found the types I've wanted after I've explored the domain space, I'll then annotate afterward to lock them in.

As with anything, YMMV.

Are you aware that some people build projects with JavaScript that aren't intended to be thrown away quickly?

TypeScript makes writing frontends easier and it makes writing Node-JS apps easier. It makes it easier to both read and write code.

It’s faster to write typescript than JavaScript. Because a) you get properties and type definitions popping up in your text editor as you write code and b) you eliminate a tonne of run time bugs

There’s basically no extra effort to using typescript if you already have a build pipeline running. It’s not like using Java or Haskell where you’re drowning in type definitions.

The draw is for people who aren't building for "throwawayability"...

Static typing, compile time type checking. Those are the big ones.

Worth noting that this is not just for your actual code. You can also typecheck (and, just as importantly, refactor) JSX-based views like React's. You can't do that on stringly-typed templates like jQuery.tmpl, Knockout templates, or similar.

If you've ever had to debug a misbehaving Knockout template just to find it was referencing a misspelled object property, you can appreciate how much cleaner TSX templating is.

Upvoted because they mentioned Vue.

Applications are open for YC Summer 2019

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