Hacker News new | comments | show | ask | jobs | submit login
TypeScript at Google (neugierig.org)
494 points by wslh 18 days ago | hide | past | web | favorite | 195 comments

> The first tempting option is to just abandon this ruined planet and settle a new one that doesn't even involve JavaScript. If only we invested more in GWT (a Google project that compiles Java to JavaScript) or Dart (a Google project that compiles a new language to JavaScript) or WASM or [insert your favorite language here — Clojure? Haxe? Elm?] we wouldn't need to worry about JavaScript at all!

I thought about this for quite a while when we started on TypeScript at Google (I work on this with Evan). I've convinced myself that using a different language cannot solve the problem that we're looking at.

The argument goes like this: if you use a different language than JavaScript for front end development, you're (hopefully) doing it for a reason. That is, you (a) want the other languages semantics (e.g. bounds checks on array accesses, runtime types, method dispatch, you name it), or you (b) might want the programming languages ecosystem - editors, IDEs, etc; but most importantly libraries and frameworks. Most likely, you're looking for a combination of (a) and (b).

The problem with (a) is that the more different the runtime semantics of your programming language are, the more emulation code you need. Emulation code is costly in code size, performance, interop with JS, and often understandability (at some point you will need to debug the output, believe me).

The problem with (b) is that you typically opt into a large ecosystem that was originally written for a very different environment. This was a big issue with GWT: people would pull Java libraries, but those libraries, amazing as many are, were not written for the web or with code size in mind. This meant using a common library like Guava required a lot of engineering effort to keep code size in check. This also applies to WASM, possibly even more so.

These mechanisms work together to make it very hard to hit the sweet spot between performance, developer experience, and interoperability. And ironically, the better you get at the goals you're aiming for (different semantics, different ecosystem), the farther you get away from a working solution.

I don't think it's impossible to achieve a transpile-to-JS language that works really well with enough investment, but keeping in mind the other reasons Evan lists (mind share, existing code base), incrementally improving JavaScript where needed is IMHO the much more promising approach.

This is a super interesting perspective. It seems to me that another way to strike this very tricky balance is to design a language with it in mind - so that you can choose semantics with the emulation trade-off explicitly taken into account - and invest very heavily in its ecosystem - so that you can catch up on the library, framework, and IDE front. Arguably both Dart and TypeScript (among others) are doing the first part of that, but only TypeScript is doing the second part. I guess there's a third important part too: choosing a really good set of semantics based on that trade-off. I think TypeScript has really nailed that one. I like Dart and Elm too, but TS is definitely in the sweet spot for me.

Unfortunately, to take this approach you generally need it to be a new language, so it doesn't have existing ecosystem baggage to carry along, which means it is less likely to win on another axis you often care about: developer familiarity.

This is why the candidates in this space are only the upcoming ones like Dart, Elm, and maybe Kotlin. The other "compile to web" approaches that use more established languages (like emscripten for C++ or GWT for Java) tend to produce larger binaries due to carrying along their ecosystem.

This is restating GP's point, but to say it again, this tradeoff is kind of inevitable -- half the reason to want to transpile is to reuse knowledge and libraries, but then by reusing those libraries you kill your binary size.

(This dynamic reminds me of all the people who hoped they'd be able to reuse their existing web apps on mobile but ended up with bad mobile apps. I think it's possible to make a good web-based app work on mobile but it's often a rewrite from an existing web site, at which point you're often rewriting anyway and might as well use a mobile-native language.)

This isn't like using Kotlin or Scala in order to use an alternative to the "original" language. The power of TypeScript is that it is designed to be less an alternative programming language per se than a dev tool for JavaScript. Instead of choosing different semantics, you're being somewhat more explicit in specifying your JS semantics. And you aren't switching to a different ecosystem, you're making your tools more powerful when working with the JS ecosystem.

Since the nature of this "tool" is an extension to the syntax, there is a bit of risk that there will be an conflict with some future JS, but other than that, the 2-factor (same but more explicit semantics, same but fortified ecosystem) analysis seems to show why TypeScript is popular.

JS did already have flavours and with ES6+ we did get an entire new language ;)

Kotlin looks promising. Sure, you can use the whole JVM ecosystem with Kotlin/JS or Kotlin Native. But it looks like JetBrains is trying to bootstrap a JVM-independent Kotlin ecosystem.

So why Kotlin instead of TypeScript?

1. Potentially more static optimization, because Kotlin is designed from the start for static typing. 2. Ability to target other platforms (Android, iOS, desktop) without adding the overhead of a JS runtime.

Why not Scala?

1. Scala's standard library is heavier. For instance, Scala has its own collection classes, whereas Kotlin merely has its own collection interfaces. I assume this is why Scala.js advertises a starting size of 45 KB gzipped for an optimized build. That's not actually very small. 2. On the JVM, Scala fundamentally gets interop wrong in at least one way: Java getters and setters don't automatically become Scala properties, as they do in Kotlin. So idiomatic real-world Scala requires more wrappers.

The one thing that worries me about Kotlin is that it has reflection instead of compile-time metaprogramming (e.g. macros). Wherever reflection is used, it impedes static optimization (e.g. ProGuard, other tree-shaking). Sure, real-world JVM work has to use reflection sometimes, but at least JetBrains should have refrained from providing an API for doing Kotlin-specific reflection, and provided something like macros instead. (Edit: And yes, the Kotlin reflection API is implemented in the JS back-end. That was a mistake.)

Oops, meant can't use the whole JVM ecosystem with JS or Native.

> The problem with (b) is that you typically opt into a large ecosystem that was originally written for a very different environment. This was a big issue with GWT: people would pull Java libraries, but those libraries, amazing as many are, were not written for the web or with code size in mind. This meant using a common library like Guava required a lot of engineering effort to keep code size in check. This also applies to WASM, possibly even more so.

Didn't GWT-RPC solve most of this ? You could simply run them on the server, which was another nice property of Java. You could actually link nearly any java library together with any app and use it, even with isolation if necessary.

Technically GWT is still an active project. They're (slowly) working towards a 3.0 release. I use GWT in my day job.

I used GWT to build an app in 2011-2012. It was my first web app, and it needed to have a desktop-like feel. GWT + the SmartGWT UI library allowed me to leverage my existing experience with Java, its IDEs and tooling, and various desktop GUI frameworks to build an app that did what I needed.

But, over time GWT became a hindrance rather than a help. The DevMode plugin stopped working as of FF27, and I had to keep around a copy of FF24 just to debug the client. The entire app had to be recompiled every time I made an edit and refreshed the page, wrapping JS libs to expose them to the Java code was a pain, and no one else on the team I moved to had ever worked with GWT. The discussion around this notional "GWT 3.0" didn't help either - it sounded as if half of the technologies around GWT would be removed, like GWT-RPC, but at the same time all the threads about it have been saying "well, J2CL is still internal to Google, we'll get it out eventually". Really uncertain future there.

I spent the next couple years working on a JS app, introduced Backbone+Marionette, and became comfortable with JS. In mid-2015, I began exploring the idea of rebuilding my app's client with a modern JS stack, and decided to try these "React" and "Redux" things I was reading about. Prototyped a client rewrite, and it was clear this was the way to go.

A few months ago that rewrite finally reached feature complete, and I got to go in and rip out every last line of GWT in the codebase. I was absolutely GLEEFUL when I did that :) The React+Redux codebase, with Webpack+Babel as the build toolset, allows us to iterate so much faster and with a better dev experience.

I can understand why GWT would still have some semblance of usefulness in certain enterprise situations, but I would never touch it again myself.

I think GWT suffered from being a bit too early. If source maps and Java8 closures existed in the early days, GWT would have been a lot more compelling.

I also did a lot of GWT work about a decade ago and haven't touched it since. But there's a lot of things I miss, and I would be willing to consider a "modernized" GWT if it ever materializes. I especially miss GWT-RPC; statically checked typesafe interfaces are just much faster and safer than hand-coding REST interfaces and hoping the client and server agree.

That said, I do think the train came off the rails when added all that crazy model-blah-blah-presenter pattern stuff. If GWT is ever going to make a comeback, it needs some sort of simple equivalent of Angular or React.

Yeah, it's kind of funny when you look at what GWT had vs what modern JS development looks like. Multiple browser targets, using the same language on both client and server, static types, RPC declarations, a dev mode server, etc.

That said, GWT-RPC also went from being nice to a pain. The serialization formats were "proprietary", in the sense that they were GWT-specific and couldn't be reused with any other platform. There were actually two separate formats. Client->server was some kind of custom text format, while server->client was _technically_ JSON, but the contents were still basically opaque. (I found a document that tried to reverse engineer the format, and it was pretty ugly.) That was another pain point, actually - inspecting API calls in a browser's Network tab was useless, because you couldn't interpret anything out of the contents. Also, I'll take promises (and `async/await`) over GWT's ugly `MyRpcInterface/MyRpcInterfaceAsync` definitions and success/failure handlers any day.

When I rebuilt my app, I was lucky enough to be able to re-expose the same internal API endpoint implementations over JSON-RPC. That let me keep my existing backend logic, and build out the new JS client separately while keeping the old one in place until the new one was ready.

I agree the implementation of GWT-RPC could have been better. It was also pretty slow if the payload was a lot of tiny objects. But I'm less enthused with promises than you are; I like GWT-RPC's programming model.

I'm surprised some sort of IDL-based client & server generator for REST services hasn't taken off.

Have you looked at Swagger's IDL?

The big problem with an IDL that people want to avoid is tight coupling, IOW, all systems have to be upgraded at once to use a change in API.

Tried Vaadin? It's a different take on the "write Java rich client code and run it in browser"-idea. It uses GWT as its "backend". They switched to GWT several years ago - too bad if they have to switch again due to GWT dying.

Could these very same arguments not be applied to Javascript itself? JS is "transpiled" to bytecode, a language with vastly different semantics and a totally different ecosystem. It end up being wildly inefficient, but consumers don't seem to mind.

The description of Dart is also wrong. My understanding is that they are aiming at REPLACING JS in the browser, not compile to it. Compilation to JS is a stopgap to make the language useful while it's left unimplemented in Google's very own browser (A fact that never ceases to entertain me). The next web language shouldn't compile to JS, it should replace JS.

As JS becomes the asm of the web, TypeScript is going to become the C of the web. Just enough abstraction to make it possible to write, but still not enough to tank performance.

That was their initial goal, but it's been years since they backed off of Dartium at this point.

For what it's worth, almost no one on the Dart team ever believed that Dart would "replace" JavaScript. The memo that claimed that wasn't written by anyone on the Dart team.

I'm hesitant to work in any JavaScript code base that isn't using TypeScript at this point. Two years ago, it was painful to use as any early release is but the benefits were obvious.

My biggest wish for TypeScript is that it was easier to use experimental flavors that supported JS features currently being considered, such as the pipeline operator proposal.

The codebase powering www.twitch.tv utilizes TypeScript and I can’t imagine working on a project of any significant size without leveraging it going forward.

So I know you also use React extensively at twitch, so how are you finding react and typescript working together?

I've been using the two together recently and its been great. Like you I don't think I could ever go back to not using typescript for anything but the smallest projects.

However, often times I've found some common react patterns to be difficult to express in typescript. Namely default props and high order components. The type signatures I'v ended up with for my HoCs aren't as simple as I'd like, but I guess there is no way getting around that.

I've actually started to prefer render props over HoCs simply because the type signatures are simpler. Still no idea how to handle default props correctly.

For the default props side of things, as of typescript 3 and the latest @types/react it should work as you would expect:


I saw that for default props, but can I use it yet?

The React typescript definitions are still on 2.8 [1], and I imagine that they plan to stick with 2.8 until maybe the next major react release? I have no idea where people discuss things like react types for DefinitelyTyped. Github issues seem like a mess due to the sheer number of different projects sitting in a single repo.

[1] https://github.com/DefinitelyTyped/DefinitelyTyped/blob/1d96...

Yeah you should be able to, the minimum typescript version required and the one they test at is 2.8 for now but the LibraryManagedAttributes type is present [1]. On 2.8 and 2.9 it has no effect but if you're using 3.0 you should see it working.

[1] https://github.com/DefinitelyTyped/DefinitelyTyped/blob/1d96...

My pet peeve with TypeScript and React isn't with React but some parts of the ecosystem, like redux-saga: there are subtle issues with using the saga operators that mean that although the compiler makes it look like type inference is working, you've actually lost the type being ``taken`` from redux with redux-saga. To maintain type safety, you need to do funny things like "typeof sagaFunction".

Little things like this can add up to subtle bugs and tech debt if you're not careful.

Maybe use the defaultProps HOC from recompose? Or take example from it!

The vast majority of web development is done using JavaScript without TypeScript despite headlines on HN and reddit.

The vast majority of web development was also done without jQuery in 2007 despite headlines on HN and reddit.

That did not mean jQuery wasn't better than the ugly ad-hoc kludges in vanilla JS most web developers used at the time.

Whether jQuery, which is written in vanilla JavaScript, was better or not has nothing to do with my point.

TypeScript was released in 2012, I wouldn't call a 4 year old tool an early release. And if you were already using Webpack picking it up was as easy as adding a loader.

IMO, using such early proposals isn't worth the risk in production. Especially for proposals that are so young that they haven't even settled on a clear spec as to its behavior, like the pipeline operator.

Sorry this is self promotion but I think it's relevant if you need something like the pipe operator now: https://github.com/egeozcan/ppipe

It's also ironic that I couldn't write this in Typescript because I simply couldn't figure out how. These days when I use my helper, I just use any and cast the result. It sucks but until I figure out how to type proxies and use variadic generic type parameters (if and when these are supported) I don't have another solution.

The "official" Typescript solution to variadic type parameters is to write a bunch of overloads covering the most frequent cases, e.g. from 1 to 5 parameters.

no yet really. But it's good first step to have "true" variadic types support. Right now I think you still can't represent stuff like `Promise.all` without many numbers of overloads.

> TypeScript was released in 2012, I wouldn't call a 4 year old tool an early release.

Goddamn time travelers, stop messing with chronology!

4-year old by the time GGP found it "painful to use as any early release", which was 2 years ago.

I could be slightly off on when I first used it by a year or two. Years start to blend together. It's almost 2019 already! Maybe I shouldn't have used exact numbers.

Either way it wasn't Typescript itself that made it difficult. There wasn't as large of community yet, documentation was much less, editor support wasn't as great and very few packages had type definition files. Definitely typed could show all or most of their packages on GitHub at the time and many were incomplete. That was the sole way to get any type definitions.

Agreed with your comment on early proposals. Still would like to have the option to use it and double check the transformation of how it outputs. And not everything needs to be for production use. Writing for fun is an enjoyable hobby.

Have you spent any real time with Flow?

As I’m starting to get into the modern front end world… I do want the safety of a stronger type system but it doesn’t look like the React ecosystem has really decided which way to go.

TypeScript is popular. But flow was developed by Facebook and so it’s obviously heavily used by some of the top people.

I’ve only been reading about them, I haven’t chosen to use one yet. But I’ve been leaning on flow since it’s developed by the React team at Facebook.

I've reported 5 bugs about Flow and can list at least 10 other bugs reported by other people that I experience on a daily basis. Most of them have been upvoted by hundreds of people. Most of them have been opened 1 or 2 years ago. Most of them don't have a single reply from people working on Flow (or one of these: "yes I guess it's a valid point", "pull requests are welcome", "it's not a bug" , "we would have to rewrite a lot of stuff", without any follow-up).

That's what really frustrates me about Flow after using it for many years. We shouldn't have to rewrite valid code, write unreadable workarounds or add // $FlowFixMe annotations to avoid Flow's issues. I lead a small team of junior developers to whom I presented Flow. We now use it everywhere. But they often experience difficulties when they try to type their code. When I see what blocks them, my answer is too often "oh yeah, it's a bug in Flow. There is an issue about it on GitHub opened in 2016".

I'm right now waiting for this https://github.com/facebook/create-react-app/pull/4837 to be merged to move all my projects to TS.

Edit: and I don't blame the devs working on Flow. I guess it's more a priority issue at Facebook. Or maybe they just gave up on the community support since TS is too ahead.

I've spent time with Flow, and I like some aspects of it (the type system seems a little more expressive, at least in the ways I know how to bend it). But it seems like TypeScript has fairly soundly won, as far as the two of them go. I've moved to writing almost exclusively TypeScript and I really don't regret it.

Although it's clear that Facebook's libraries, among which React, favour Flow, there's strong community demand for TypeScript even around React. Thus, the type definitions that are available for React are excellent, Redux even includes its type definitions natively, and most of the large tools in the React ecosystem work pretty well with TypeScript.

The main large project you're likely to use that does not really play well with TypeScript yet is create-react-app. There's a TypeScript fork [1] which works reasonably well, but "reasonable" is not really what you'd hope.

That said, the strong community push means that they're at least considering it. [2]

[1] https://github.com/wmonk/create-react-app-typescript [2] https://github.com/facebook/create-react-app/pull/2815

We're actually looking at removing the type definitions from the Redux core and punting them over to DefinitelyTyped, because neither of us primary maintainers use TS ourselves and we don't have the experience to maintain the type definitions.

Also, the CRA-TS fork runs, but the one time I played with it was when I tried to help another team set up their project, and that's when I found out it has _ridiculously_ restrictive default linting rules. Every lint error is a compile error, and it flags things like using arrow functions in render methods, which is absurd (see discussion at https://github.com/wmonk/create-react-app-typescript/issues/... ).

The first thing I do in a new CRA-TS project is make the tslint.json rules default to warnings instead. Or just disable them completely. After that, it's great! I'm actually surprised that they still haven't loosened the rules after Dan called it out a month or two ago. Seems like an easy enough fix to at least make them warnings until they choose better defaults.

Haha right, it's still the case that the type definitions for Redux are very much usable though :)

I agree, the TypeScript team loves React and one of the reasons I started using React was because JSX/TSX is one of the few ways to type check views.

I have been maintaining some boilerplate to demonstrate TypeScript + React SSR that should point the reader in the right direction https://github.com/styfle/react-server-example-tsx

Here is another PR, more recent, based on Babel 7 and its TS support: https://github.com/facebook/create-react-app/pull/4837

I'm waiting it to be merged to switch to TS.

Create React App is the first link that TS gives you in "getting started". Is there something wrong with it?


CRA is a set of packages, among which the most important is react-scripts (contains all build and publish commands). For Typescript you use rect-scripts-ts, a fork that usually is some versions behind the main one.

It does work fine, but sometimes you don't get some of the gooddies that you get in the latest js version.

From my personal experience, Flow prioritises soundness in its type system, and thus can catch some bugs that TS won’t, but the TS tooling and editor support is drastically better than Flow’s.

Edit: oh and it’s worth noting that I’ve had much more luck finding TS definitions for third party packages than I have with Flow.

Could you expand some more on the tooling/editor support?

I’ve only done a cursory look. My editor (IntelliJ) supports both to some level. Webpack/Babel do too.

I’m very new to writing React and modern front end JS so it’s quite possible there are things that I should be looking out for that I don’t even know about.

Typescript compiler architecture is quite different to flows. Typescript was written from the get go to provide really fast and accurate intellisense to IDEs. The newer refactoring powers are super nice too. Most ides just ask typescripts language service “hey, my user’s cursor is here, what should I show for code completion?”

I think that’s what differentiates TS from flow. Typescript thought about the whole developers workflow while flow is just a compile time typechecker.

To Flow's credit, their language server does provide IDE features:


I still have found TypeScript to be an overall more pleasant developer experience, though.

That’s awesome, I didn’t know that.

At this point, I think Flow clearly has a minority mindshare & is looked at more skeptically all around the JS ecosystem, and maybe even the React ecosystem based on what I see talked around. TS does a much better job integrating with existing JS and is much more practical about incremental updates whereas Flow bleeds all too easily into needing to add typing to a significant amount of code in order to add a type.

That's not to say that either TypeScript or Flow are perfect - they both are constraining with typing when it comes to composing functions last I checked.

I didn't have too many problems with typescript and ramda. I occasionally have to explicitly send in types to the first function of a pipe, which is a little annoying, but for the most part it seems to just work for how I use it. What problems have you run into?

Have a look at the typescript declaration for Node's util.promisify (sorry on mobile can't find it right now). It's something like 10 lines long and covers only a handful of cases.

It's not something you'd want to find in the middle of your code, yet you may have to if you want to do generic/functional programming in TS.

I worked with both. Without going into details - I recommend TS as it's better documented and easier to work with. With 3.0 they also improved error messages.

EDIT: one thing I miss from flow is https://github.com/gcanti/babel-plugin-tcomb - it's quite handy to spot data errors (before you have big static coverage)

For what it's worth typescript is developed by Microsoft. Doesn't get much bigger than that

I know, and that’s a definite plus. I don’t have to worry that it will go away or lose all the main contributors.

But is not developed by the same developers/company as React.

I will say given what TS is competing against the fact that it so well used is rather compelling. I know all of Angular is also written in TS. It’s clearly very heavily used.

React can fade but JavaScript won't..(it could only evolve). outside react Typescript is the clear winner and even most of the react projects I am seeing is using Typescript. I would say Typescript is the clear winner. Also VSCode is now far popular than other editors which is developed by Microsoft as well..

Also typescript and React go really really well because typescript can do tsx which is a strongly typed flavor of jsx.

Being able to use good code completion when using other people’s components is a huge boon.

Isn't React in itself a view library? What's there to develop on it?

I'm really interested in this, as I'm a happy Angular user. (I'm primarily a non-frontend dev/tech/ops, but I occasionally I do frontend development.) So every time I look at a React component/codebase I'm completely lost, and I'd like to understand why and what and how.)

I hope the work they did with the Babel team with help with this.


I'm really eager to see availability of some extra features via this new pathway.

But I am less excited about projects containing TypeScript plus the large number of transitive dependencies from a typical Babel set up; I've been greatly enjoying TypeScript instead of that.

I am looking forward to see some production ready versions of RY latest project Deno "A secure TypeScript runtime on V8"


Written in Go rather than C++ no less.

Edit: wait it looks like they’ve changed to all Rust with C++ for the libraries. I haven’t looked at the codebase since the spring. Am I crazy that i could have sworn it was written in Go previously?

Thanks guys. I'm out of the loop.

It was in Go, but in Ryan’s announcement, he said he was considering switching, and has since done so.

Cheers, Steve. I missed that.

100% agreed. It was incredibly liberating to move from Babel with its byzantine level of configuration and plugins to "just run tsc". So much easier to reckon with - Typescript is Typescript is Typescript.

For my part, my web projects have generally ended up with both Typescript and Babel because of old-browser-support reasons, so integrated parsing simplifies things for me.

Until this showstopper is fixed (it's been almost 9 months now), some of us can't move forward with Babel 7: https://github.com/babel/babel/issues/7074

Yeah, agreed.

If I were looking for a regular job, I would probably filter employers based on whether they use TypeScript or not at this point (assuming it was some JavaScript-adjacent project). I'm not sure if there's really a good way of doing this sort of filtering.

That's the main reason I use Flow almost exclusively. I don't like sacrificing really useful features for the sake of a cleaner code base.

> If only we invested more in GWT (a Google project that compiles Java to JavaScript) or Dart (a Google project that compiles a new language to JavaScript) or WASM or [insert your favorite language here — Clojure? Haxe? Elm?] we wouldn't need to worry about JavaScript at all!

I'm on the Dart team. I don't know if the author intended this, but you could read this as saying that Google isn't investing much in Dart, which isn't true.

Flutter and Fuchsia are the high profile projects that use Dart. AdWords is also built in Dart. The Dart team itself is as large as its ever been and growing. (I'd give more precise numbers, but Google generally shies away from publicly stating personnel details.) We have a ton of internal and external code written in Dart, and it's growing at a nice clip.

Different projects have different needs. If you have a large existing JS corpus that's providing a lot of value for you, then an incremental migration to TypeScript makes sense.

If you're looking to rewrite a lot of code and pay off technical debt anyway, then moving to a new language that doesn't have all of JavaScript's baggage can be a smarter choice. Dart has a cleaner object model and fewer warts like "===", etc. Making a bigger break from JS means that Dart's type system can be simpler than TypeScript's and is sound. That in turn means the compiler can rely on types for optimization and minification.

I mostly know Typescript, but I'd like to learn more about Dart... particularly where the type system differs in theory. Do you have a good recommended article on that?

The other question is the community one: if Dart requires type bindings (like TS .d.ts files) to the large community of JS projects, how does it plan to solve the kickstart problem. It's taken TS community many years to over just the popular js libraries out there. Imho, I'd make a utility to convert/translate TS definitions into Dart wrappers... but that would require to support TS primitives almost 1:1.

None of this is meant to sound critical, I'm just genuinely curious on the process of language development.

> Do you have a good recommended article on that?

I don't, but I agree it would be useful. We're not where I wish we were in terms of docs right now.

> if Dart requires type bindings (like TS .d.ts files) to the large community of JS projects, how does it plan to solve the kickstart problem.

We actually have a tool that will generate the proper Dart interop bindings given a TypeScript .d.ts file:


> It's taken TS community many years to over just the popular js libraries out there.

Dart is different from TypeScript in that we are deliberately a more batteries-included system. We wrote and maintain a full set of core libraries (collections, async, etc.) and Google has a well-funded team to ship and maintain a full-featured web framework (AngularDart).

So we aren't as stuck needing to rely on the JS ecosystem as TypeScript is. There is still tons of useful functionality that's available in JS and not yet Dart, which is why interop is important, but we have a lot of customers that can get by without needing much or any JS interop.

> If you're looking to rewrite a lot of code and pay off technical debt anyway, {snip}

Also if you're writing something from scratch.

I see four of these statically-typed better-than-JS languages with familiar syntax that, while having their own VM (or compiler, or both), can also compile to JS:

* Dart

* Haxe

* Kotlin

* Reason

Google has enough resources for someone to write a transpiler that can take annotated JS and convert most of it to TypeScript. It's certainly much more pleasant than having to type random comments everywhere, which kinda makes syntax highlighting way less useful. Oh, and last I checked there were no editor plugins for linting Closure Compiler annotated code.

Another option would be to add TypeScript support to Closure Compiler, although it doesn't seem likely since there's no spec to guarantee compatibility.

I'd love to see Facebook, Google, and Microsoft team up in this space, instead of creating 3 separate but very highly similar tools.

Also, while we're talking about Closure, let's take a moment to appreciate its amazing UI toolkit [0]. I'd still consider many of their widgets to be the gold standard. It's written with desktop clients in mind and is incredibly feature-complete. I believe it also has pretty good accessibility, although I haven't personally tried that out. Oh, and don't forget the i18n as well! The closure library definitely has a lot of quirky aspects to it, but it's still quite amazing if you consider its age and how much stuff it supports. It's worth taking a few minutes to browse through their docs [1].

[0] https://google.github.io/closure-library/source/closure/goog...

[1] https://google.github.io/closure-library/api/

I couldn't tell from your wording if you knew this already, but we wrote a JS->TS converter too. I didn't call it out very clearly but it's the second to last link in the post.

I am really sad that TypeScript gave up on their spec. It previously was one of the strengths of the language that I was happy to cite. I guess it's a common crutch for languages (Python and so on) to say "the implementation is the spec" but without a spec to guide you, you lose sight of which features are intentional or accidents or even what the distinction between the two are.

The Closure library does has some great stuff in it. It's the accumulation of years of experience of working around lots of really subtle issues in lot of browsers. On the other side it also has a lot of code for issues that are obsolete, and it's hard to know which pieces are for what.

Google did a bit of work on converting Closure annotated JavaScript to TypeScript. It's called Gents and it's part of the Clutz project https://github.com/angular/clutz/tree/master/src/main/java/c...

We used it at Lucid when we converted our codebase from Closure annotated JavaScript to TypeScript. https://www.lucidchart.com/techblog/2017/11/16/converting-60...

Google has support for using TypeScript in Closure annotated JavaScript via Clutz: https://github.com/angular/tsickle

It also has support converting TypeScript to Closure annotated JavaScript via tsickle: https://github.com/angular/clutz

Before we converted all of our codebase to TypeScript we used both Clutz and tsickle. It was complicated to setup, but it worked. Now we just use tsickle. It's great to get the optimization of the Closure Compiler while using TypeScript.

http://www.syntaxsuccess.com/viewarticle/closure-compiler-vs... - interesting article about how closure enables smaller bundle sizes.

I agree, it would be cool for someone to do the same thing for Typescript, I seem to remember a repo a while back on Github that said someone was experimenting with it - cant for the life of me remember where though!

didn't read the other comment on this - https://github.com/angular/tsickle was the repo

> I'd love to see Facebook, Google, and Microsoft team up in this space, instead of creating 3 separate but very highly similar tools.

It'll probably happen anyway, but the current competition will determine which tool that will be. So far TS looks like it's winning it, but, clearly, not by a large enough margin that the industry coalesces around it - yet.

TS included Flow features over the years (control flow based typing, strict null checks, etc.)

I feel like this sort of organic growth (for typescript) is a very healthy sign for a project.

ES6 (or whatever we’re supposed to refer to it as now) is good enough for many things, but when you see it used heavily with, for example, proptype hints... you get the feeling that there really is a trend these days towards flavoring static type checking and the error checking that offers.

I think its an interesting shift, with python and javascript both being poster child dynamic languages, but people who use them seriously going... ‘yeah, type checking is actually pretty handy...’.

I feel like for production I would want a clean upgrade path to whatever JavaScript implements in the future. Can typescript and code converters provide this? (The article sort of touched on it.)

Sadly, standards seem to be sitting on their thumbs with weak excuses - people doing it different ways therefore we do nothing. Just take the larger market share compiler, add a few handy features from others and call it a day.


One of the goals of Typescript is to be closer to what JavaScript _will be_, rather than create something new. You won't see chunks of code that need to be rewritten.

That said, yes, you can compile TS to JS with no ecmascript compatibility constructs to just remove types and essentially "eject" TS into JS.

Sorry if this is a well known term but what is a "proptype hint" in this context? I can't seem to find any references for '"proptype hint" "javascript"' or any variations that come to mind on Google.

Edit - changed previous sentence to "proptype hint". I originally erroneously read the parent as saying "prototype hint" which I couldn't find results for, but even after correcting my reading error my question still stands.

`PropTypes` are a library for runtime type checking of props for React components. It was originally part of the React core, but split out into a separate library with React 16.

PropTypes are used for a combination of debugging during development ("you accidentally passed a string instead of a number", or "you forgot to include a required prop"), as well as documentation for a component. React devs have traditionally used PropTypes to act as readable documentation of a component's expected props, and there are tools that can extract PropTypes usages and generate documentation files.

However, with the rise of TS and Flow as static type systems, the need for a runtime-based type checker has gone down, especially since people using TS/Flow have probably already declared types for a given component's props.

I believe they’re referring to the PropTypes Library that grew out of React. It’s extremely limited in scope compared to something like TypeScript, but it does give you some benefit.


github.com/facebook/prop-types is the 2nd google search result for this term, and is what I was referring to, although the first result (devhints.io/react#property-validation) is arguably a better summary.

Ie. ‘lite’ type checking, used in react.

(did you perhaps see the results for ‘javascript prop type hint’ as a google autocorrect suggestion or something? This is a well known term, but I’m pretty amazed two seconds of google didn’t discover what it was...)

I read it and thought you were referring to something related to some proptype based code completion. The use of 'hinting' threw me off completely, especially when you're talking about checking & validating.

Yes I found the prop-types library, but it doesn't include the word "hint" and I couldn't find any documentation that did. I assumed there this was an obscure term of art you were refering to.

At this point I feel JS won't have to evolve much unless some useful feature needs JS itself to be extended but let AltJS take care of usability and just concentrate on rock solidness, performance and portability between runtimes and developers can just use whatever shiny new version they want to use that runs on old but battled tested runtime without waiting for the whole internet to upgrade.

That isn't going to happen with Typescript. Aside from the type system, Typescript won't be implementing new features until they are in the ECMAScript standard.

I wonder if it's worth migrating from Flow to TypeScript?

Flow has been great, but I've just tried to update to the latest version and I'm dealing with a flood of indecipherable errors, especially from the react-dnd library. Looks like no-one is really maintaining the flow types so I'm on my own, and I don't even know where to start.

I also haven't been able to track down some errors, like "Cannot read property 'foo' of undefined". Flow thinks that this variable can never be undefined, and I have no idea how it's happening. It might even be a bug in Immutable.js, but I have no idea.

So if TypeScript is more popular and has a bigger community, then maybe it's worth migrating just so I can get more help with these issues. And maybe TypeScript will catch more cases as well.

That's what I did. I switched to TypeScript after two years of being both heavily invested in Flow and advocating it.

The reason I initially chose Flow was the fact that their goals were more ambitious (trying to build a sound type system for example). And there were features that Flow had and TypeScript didn't (tagged unions for example).

The reason I ultimately switched to TypeScript was that after a couple of years, it had simply caught up and surpassed in the one area it was behind Flow (i.e. expressiveness of the type system and type-level programming), and that it had widened the lead in the areas that it was always better at, like much better tooling, bigger community, core team being more engaged with the community, releasing RCs to smooth out the rough edges, etc.

So yes, I switched to TypeScript, and I see that I'm spending less time working around the type system's quirks and more time getting things done. I'm also very much enjoying the fact that I can express types in TS that I never could in Flow. So my codebase has much better type coverage in TypeScript than it did with Flow.

[0] https://www.typescriptlang.org/docs/handbook/advanced-types....

> much better tooling

If you have the time, would you mind commenting specifically on this?

I'm using Flow, rather than TS, for a bunch of reasons you are probably familiar with, but over time I'm just wondering more and more if switching to TS might be worth it just for the tooling.

With Flow in VS Code (via the flow-for-vscode plugin), whilst things have slowly and steadily improved over the last 2 years it is still quite a way from 'just works'. I get the impression that the story for TS with VS Code is a lot different, and everything would just work out the box (intellisense, auto import, meaningful error messages tied to line numbers, etc) though I simply haven't yet found the justification to invest the time in migrating just to check this. If I'm wrong and it's the same or only very slightly better, it would obviously have been a time sink for not really much benefit.

Do you have any insights or advice on this? Even if you're not a VS Code user, what tools do you use that are better with TS than Flow?

Well, we had a 50K sloc codebase written in Flow. We had invested heavily in the type system for quality control, so we had types everywhere. This made it riskier for us to switch to another type system, which is why we stuck with Flow for longer than we should have.

The way I finally did it was that I tried out TS on a side-project that I wrote from scratch. I did expect better tooling with TS, but I was still surprised by how better the experience was.

Auto import just worked. Same with code navigation. And they made me work much faster. Intellisense was also much better. And the error messages more readable. (And they've gotten even better since)

All of these things work to some extent in flow+vscode, but the experience with TS was incomparably better.

I was still hesitant to switch the larger project to TS though, mainly because we were using some of Flow's more advanced features to type-check a function like `wrap()` in this code:

  const obj = {foo: true, bar: {baz: 2}}
  const wrappedObj = wrap(obj)
  wrappedObj.get('foo') // returns true
  wrappedObj.get('bar').set('baz', 'some string') // type error. baz must be a number
This was almost possible to do in Flow using `$ElementType<>` and `$Call<>`, but TS had no counterpart for `$Call<>`. Luckily though, TS soon came up with conditional types, which turned out to be a much more reliable way to handle these cases.

That's when I decided to switch the codebase to TS. It took about 5 days. It wasn't straightforward, but in the end, it gave us a much smoother developer experience.

If you're already using VS Code, I expect you'll find TypeScript support to be much, much nicer, since VS Code is the not-quite-official editor for TypeScript programming. VS Code is written in TypeScript, and I believe the TypeScript and VS Code teams (both at Microsoft) collaborate with each other to improve the developer experience of the two used in combination. For example, here are some TypeScript release notes showing the improvements to the TS language service and how they manifest in VS Code:


TypeScript has a nice architecture that provides a language service that can be used by any editor, but my impression is that VS Code is the "flagship" editor that gets these features first.

I personally use WebStorm, and I find its TypeScript support much better than its Flow support in various ways (though I haven't tried Flow in a while). Imports get added automatically, autocomplete is fast and has better results, navigation just works, etc. Part of this is historical: WebStorm supported TypeScript first, and was hesitant to support Flow during the long period of time when Flow didn't work on Windows. It now has Flow support, but I think it's just not as polished, and I don't see it come up as much in the release notes.


We’re going through a similar process at my company - how do we refactor the decade old startup-style JS without 1) spending a year rewriting everything from scratch generating little business value and potentially introducing regressions in the process 2) continuing to build stuff on that shaky house of cards. It looks like the solution we’ve kind of settled on has also been TypeScript. At this point it’s probably sub-5% of our prod code that’s TS source, and it’s daunting given how much we have to change and how many years it will take at our current pace, but it is the middle ground moderate way and probably the right way to approach things like this.

In my experience old JS code suffers from lack of structure and discipline much more than type safety. Can you provide an example where that isn't the case in your codebase?

Nope, that’s absolutely the issue. But we figure we can do both at the same time, and type safety hasn’t hurt anything.

Have you looked into Flow? This is the type of project it’s suited for (gradual typing). Facebook were in a very similar position when they created it. You can add a Flow pragma to a file and immediately get useful feedback based on Flow’s type inference.

TypeScript supports doing that as well :) https://github.com/Microsoft/TypeScript/wiki/Type-Checking-J...

In theory Flow has a stronger inference engine than TypeScript, which means it's more suited to incremental adoption.

TypeScript is based on an AST; which means it's inferences are limited. For example it requires you to type the parameters to a function. If the return type is derived from untyped parameters then TypeScript falls back to typing the return type as 'any'.

Flow maps the flow (hence the name) of types throughout an application, which means that it can derive the signature of a function based on the types that are passed into it. That should mean that it's a little easier to add to an existing project.

Here's an example of Flow finding an error without any type annotations: https://flow.org/try/#0PTAEAEDMBsHsHcBQBjWA7AzgF1AQwCb4BMoAv...

And TypeScript missing the same error: http://www.typescriptlang.org/play/#src=const%20add2%20%3D%2....

Thanks, I did not know that!

TypeScript can do type refinements based on the flow (e.g. a null check refines a type with null to one without) but can't do what you just showed. Are there any tools that can emit the inferred types to source code? I just now got a vision of using flow style type inference to gradually augment a project with either flow or TS types with very little work.

Flow has an API that can expose its inferences. There are Flow to TypeScript conversion tools that might bake the types into definitions.

Ironically, we’re considering switching to TypeScript and in my team the lack of inference is seen as an advantage. It forces people to consider their types as part of the design of their interfaces.

You can do it step by step when you need it, we had about 5% Typescript in the biggest project in my company when I started, now it's about 70%.

I haven't used it in a while. Does it play nice with plain-JavaScript libraries from npm yet?

I quit using it a few years back because it was a _nightmare_ having to write d.ts files for everything or be unable to use noImplictAny for your own files. `AllowJs` wasn't even a thing when I started using it, but even after its addition, this problem continued to be absolutely disastrous for my project. I remember being very disillusioned with it because all of their materials (website, docs) kept hammering on how effortless and incremental it was to use with JavaScript, yet `AllowJS` wasn't even a thing for the longest time...

I also had very severe issues with its importing of npm modules, even ones that supported TypeScript. Sometimes it would double-parse bundled d.ts files resulting in a huge error output. Other times it would just completely fail to resolve import paths no matter what I tried.

I remember various workarounds like having to define empty modules for each plain-JS import, or using `///` imports for certain files, and it was a nightmare (and I found many similar issues on StackOverflow that were unsolved). The maintainers at the time considered these terrible workarounds as valid solutions, and thus would almost not even entertain reports regarding these problems.

It's got to the point where, for me, TypeScript support is an important feature of a library that influences my decision whether to pick that library over another. Luckily, most of them these days either ship with their own definitions, or have them available.

Bottom line: I never write my own definitions for other projects.

There are very few libraries that I need to write type definitions for. However, they do not always get them right and sometimes can prove to be annoying when the typedefs do not keep up with latest versions of the third-party library. Any library I write now is done with typescript so typedefs are automatic which is fantastic.

I don't have any problems, just use require() for libraries that don't have TypeScript definitions. I wouldn't bother writing .d.ts files for the libraries you use, just be more careful using them.

Real big fan of TS, like anything though you just have to be disciplined when using it. Type absolutely everything and set the transpiler to the most aggressive checks possible... If you’re being lazy and putting : any everywhere and then complaining about how good it is...you’re doing it wrong

In our project I’ve found we make a lot less mistakes than with pure JS and there’s a lot less pointless type check unit tests due to the guarantee’s it gives us. io-ts (https://github.com/gcanti/io-ts) around rest endpoints checking json input as well has been a godsend.

I always use it with

> "compilerOptions": { "strict": true }

But given the huge number of other options I worry that like GCC's '-Wall', that doesn't actually give you the strongest possible type checking. Anyone know about that? My aim with Typescript is to turn JS into OCaml.

You might like https://bucklescript.github.io/ Facebook use it in Messenger.

> My aim with Typescript is to turn JS into OCaml

If that's the goal, why not use the real thing http://ocsigen.org/js_of_ocaml/ ?

So... ReasonML?

I share your view! Unfortunately, getting devs to write proper unit tests is – for whatever reason – difficult.

Types just smuggle themselves in with the rest of the program (granted they only cover a subset of the bugs tests do).

The author says they contemplated an “abandon this ruined planet” option, mentioning Haxe/Clojure/Elm as alternatives. I'd love to read their follow-up post to learn what kept them on planet JavaScript/TypeScript.

The alternatives to TypeScript seem increasingly compelling to me.

It was good to see Haxe mentioned even in passing; I really enjoy using it and — as others have noted[1] — it feels like a “better” TypeScript.

Haxe has great features both at the language-level (pattern matching, algebraic data types, array comprehensions, and more[2]) and tooling-level (cross-compilation to JavaScript, native code and dynamic languages, a fast compilation server[3], good VS Code support in Haxe 4, and a bunch of cross-platform game frameworks[4]). I wish more people would try it! https://haxe.org/

Reason is also compelling; it will be better still once Bucklescript's Belt library is out of beta and some warts in Reason/OCaml are smoothed out — lack of ad-hoc polymorphism[5] and lack of unicode support without BuckleScript string literals being two examples.

[1]: https://news.ycombinator.com/item?id=10009290

[2]: https://haxe.org/documentation/introduction/language-feature...

[3]: https://haxe.org/blog/nicolas-about-haxe-episode-1/

[4]: https://haxe.org/use-cases/games/

[5]: http://ocamllabs.io/doc/implicits.html

The mastermind behind our TypeScript project commented on this topic here:


I used to tinker a lot with OCaml around 13 years(!) ago. It's neat to see people are still working on fixing some of its problems. It would be fun to find a reason to use it again.

[Irony on] It's somehow reassuring that Google engineers also "check StackOverflow for answers". Helps me to raise my low self-esteem. :D I thought all what Google engineers do is writing code from scratch in brainfuck all day long.[Irony off]

Of course I am just joking. Well, the author faced the same dilemma that we all face when instead of joining the next-to-be-unicorn startup we join an established company which has been operating for more than one decade. Namely legacy code.

They should pick up a copy of 'Working effectively with legacy code'. They might extrapolate some of those advices and apply to their situation.

Isn't Reason/Ocaml a better direction than Typescript? I believe that TS is a step forward but I'm afraid that we are still in a muddy path.

I hear ya, but the author of the article needed something that could be adopted _incrementally_. JS is a subset of TS. Throwing some typing onto a JS file is often trivial. Reason would be a whole different story. Learning curve alone...

As somebody migrating a React codebase from JS to TS, I can't believe how popular TS is.

It seems like something that only exists due to the popularity of Angular, where I can only assume the experience is significantly better than with React.

The type system is frankly disappointing, and the errors the compiler spits out at you (besides the most obvious ones) are almost always useless or gibberish and at times even more harmful than helpful.

It's better than nothing I guess, but I can't help but feel extremely underwhelmed with it given how many people use it. Are all of the people in this thread Angular developers or something?

I can believe how popular TS is and it is super useful. I would not write a React application of any noticeable size without TS (and just FYI I would never willingly write an Angular app). The reason that I get far superior code completion and meaningful warnings / errors is sufficient to add a few annotations here and there.

Many people are doing TS wrong. They add types everywhere. Honestly, you should write as many types as necessary, but not more. Use type inference which works remarkably well.

At least add them on function return types and annotate types on common objects so that you don't have objects lingering with wrong property name/type or redundant properties that would be confusing to review.

It helps to create a type reference for your database schema, so you don't try to insert something weird or insert with missing columns.

> The type system is frankly disappointing, and the errors the compiler spits out at you (besides the most obvious ones) are almost always useless or gibberish and at times even more harmful than helpful.

I'd love to see examples of such errors. (And, ideally, accompanying code example)

I'm not at a desktop or laptop where I could provide you with a proper example, but the most obvious pain point is HOCs.

I was receiving an error complaining about a missing prop on a component I was wrapping with `injectIntl` from `react-intl` and could not for the life of me figure out what was wrong. Searching the type error wasn't helpful, and it wasn't until I really dug down and spent about a half hour of my time that I realized it was because we had something like `injectIntl(connect(foo, bar)(SomeComponent))` instead of `connect(foo, bar)(injectIntl(SomeComponent))`

The type error did not in any way make that clear or obvious. If I had to compare it to anything, it would probably be the type of error messages you see if you play around with type level programming/dependent types in Haskell. Or the types of error messages you see when writing Clojure.

I feel you and I think it is more of a "React + TypeScript" problem than a TypeScript problem.

We have started using Angular 2 (now.. 6?) with TypeScript for a project last year and I never had big issues with TypeScript.

Last month, one of our teams started a React project and given the success of using TypeScript before, they opted to do the same with their project. I've walked them through a few things but found myself getting frustrated a lot with weird TypeScript errors. Especially things like typing your Props was such a nightmare that we resorted to "any" a lot more than I'd like.

The project is not using TypeScript 3 so I am unsure whether that would get rid of some problems but React + TypeScript was just a frustrating experience for us.

Using TS3 with ours and the problems are definitely still there.

I think the most immediate and obvious pain point for me is typing HOCs. It's basically a matter of rearranging how you apply them until TS can automatically infer a type for you. At the same time, using `compose` instead of applying them individually solves that problem but results in strange types (that are different from the type TS infers if you apply the HOCs manually yourself in an order that makes it happy) that I suspect will cause type errors down the road when we convert the files that make use of it to TS as well.

What TS version are you on? The error messages are definitely one of the weak points, but they've been massively improved for many cases in 3.0.

FWIW I use Typescript with React, have had very few bad experiences(but not zero) and I'm never going back.

The most recent, 3.0.1 I believe? Or 3.1.0 - whatever it is.

As far as going back goes - it's preferable to plain JS I guess? But that's not saying all that much. I don't know - I'm sure I'll appreciate it more after this migration period is finished and things start to stabilize, but as of right now I'm definitely not enjoying it.

I used TypeScript with Mithril and I really liked it. I'm not going back to plain JS ever again.

> But that's what we engineers do: we make interesting compromises that attempt to balance different concerns.

I like this :)

After a few years with both TS and JS my verdict is that TypeScript definitely helps, but mostly with type-related bugs - with proper testing you don't get many of those.

What I would like to have in TS is a more expressive type system - the current is somewhat basic(e.g. you can't have a Symbol as a dictionary key - interesting given that it's possible in JS. Also you can't mix dictionary fields with regular ones in one class/interface).

EDIT: typo.

The point of type checking isn't so much to prevent bugs in production, but to speed up your development loop by catching many errors before you've even saved your file. Its much faster to see a red squiggly right after you've written a line of code, and fix it, rather than figure out whats gone wrong 10 minutes later looking at a stack trace in your test suite.

Doesn't this 100% on your personal develop workflow? I for one have been forced to use typescript in the past, and am personally very happy that I don't have to anymore.

I don't understand language design or expressiveness but I'm ok with going slow and being restrictive.

I think what we need is a subset of JavaScript, not a superset. There are things we should not be able to do in JavaScript in a web browser because to me that's where JavaScript belongs. I think the whole idea of js on the server or in other kind of projects is very silly. But that's besides the point.

But I agree with your example of symbol in dict. I would be surprised if it isn't already on the roadmap. Have you tried reaching out to the typescript people?

> But I agree with your example of symbol in dict. I would be surprised if it isn't already on the roadmap. Have you tried reaching out to the typescript people?

It's not just on the roadmap, it's in code review/iteration as of last week: https://github.com/Microsoft/TypeScript/pull/26797

Google Maps definitely made JavaScript cool at a time when it was not much in favor - people still thought Java Applets or Flash were going to rule the web.

I wish they would make a JS/TS-based version of the Closure compiler. I suspect a lot of apps would benefit from the compilation and we'd see much smaller bundle sizes. But the Java dependency is a burden to bear.

There's a JS version of the Closure compiler [0].

And the version shipped on NPM [1] has options for either native, Java, or JS.

[0] https://github.com/google/closure-compiler-js

[1] https://www.npmjs.com/package/google-closure-compiler

Isn't there already one? I seem to recall that it mostly works, just much more slowly than the java version

Edit: here you go: https://www.npmjs.com/package/google-closure-compiler

Nice! Didn't realize this was a thing. I suspect they could make even more aggressive optimizations if they made a TS version.

This idea is probably worth a post of its own. I believe that because TypeScript's type system is effectively advisory rather than guaranteed ('unsound'), you cannot rely on it for optimization unless you're willing to unpredictably break programs.

Hey, that’s an interesting thought!

If you go all the way and make it sound with variance annotations, banning asserts & under specified types, etc. then you end up with a language that sucks to use in practice.

If you go to the other extreme, you don’t have static types at all.

If different parts of your code are typed to varying degrees, or you use a lot of unsound types/inferences, maybe there’s a way to assign a confidence score to every type to indicate how accurate you think it is. Maybe there’s a clever way to statically compute that score, or you can instrument some % of prod traffic at runtime to observe types with lower confidence (Node has this, or see MonkeyType or Reticulated Python). Then take that info and feed it into Closure compiler.

> If you go all the way and make it sound with variance annotations

Variance annotations aren't quite what would make the language (in strict mode) sound. Specifically, what makes it unsound is the `any` type (generally) and the lack of enforced variance on methods, non-function properties, and index signatures. It doesn't need annotations to determine variance - type parameter variance can be inferred from where in a type a type parameter is used. It already does so for functions (that's the strict flag's strictFunctionTypes subflag). The real issue is that far, far too many people rely on, eg, unsound array assignments (array aughta be invariant over what it contains but it's often treated covariantly), for it to be reasonable to be a default. However it could always be changed (or added) in the future - that's what the strictness flags are for, ideally; providing ways to ratchet up the safety such that it won't permanently break longtime users of the language.

As far as I understand it, every sound language eventually has to fall back to runtime checks to maintain soundness in tricky cases. For array covariance I know that Java/Dart eventually use runtime checks on array accesses to verify the types work out.

However, it's kind of against the spirit of TypeScript to insert runtime checks. For example because the type system models 'undefined', to model out of bounds array accesses you'd either need to make every array access have type T|undefined or insert bounds checks that throw. (I believe Dart does the latter.)

Totally agreed. The reason to have variance annotations is the language becomes unusable without them. Thats why so many languages with object subtyping support them.

I love typescript as a JavaScript developer, but having used go for personal projects, I find the type system complex (maybe necessarily so). Having said that, I cannot thank TS enough for how it’s made life easier when working on and refactoring large codebases.

I don't know what you find complex about the type system, but I actually find it slightly limiting. They keep improving it, so it can express about 95% of what I want, but I still hit situations where I can't tell the compiler everything.

I'm the same. Anything I do, I make sure it's in typescript because I find it easier to write than standard js.

Generics are a complex concept for people to grasp without some time playing and reading docs, but once you learn it, you can express almost everything you want.

But for simple projects you can get away with all but the most basic of generics, if any at all.

With the release of conditional types, I find most of my js typing cases are covered.

Though tbh I've always leant toward the side of "if you can't express it easily, then you're being to JavaScripty".

My comment was in the context of having used Golang. It maybe a personal experience as I primarily come from dynamic, weakly typed languages, and TypeScript and Golang are my first serious foray into typed languages.

What sorts of things do you have trouble expressing with the type system?

I can't think of something off the top of my head, but it's usually related to generics. I'll type something that makes sense, but the compiler doesn't like it.

Another issue is that handling of string literals as types can be wonky when they're being compared against the type "string", which they should always satisfy but sometimes don't.

I’d love to see examples for those, maybe drop a comment when you run across a specific issue.

same feeling. I tried to use TS for several times, but it looks its type system is too complex. So I'm still sticking to old JavaScript now (before ES5) for the simplicity.

I think the most fascinating thing here is that Google are turning to a language developed and maintained by Microsoft.

They forked it for a while, called AtScript [0] and then later merged efforts. So don't think they didn't try. There's things like Tsickle [1] that converts typescript for their closure compiler

[0] https://en.wikipedia.org/wiki/AtScript

[1] https://github.com/angular/tsickle

It's come to a time that discriminating MS was an old thing.

Or maybe it's about Microsoft's continued influence, especially in the Open Source community.

Web shouldn't end up this way. Web was designed for sharing documents. Webs and webapps now are sluggish and take soooo much RAM. I have a pretty fast computer with 16GB RAM but running all these webapps with Megabytes of javascript is bringing back -5years experience and can fill up my RAM. I know it is still improving but webapp developers are also quick with abusing every performance gain often for unwanted and unneded functionality. For example CSS animations for every mouse over, material clicking highlights are terrible, terrible design decisions which occassionally even spin up my laptop fan.

> Gmail engineers had to worry so much about Internet Explorer's poor garbage collection algorithm that they'd need to manually hoist string literals out of for loops to avoid GC pauses.

What does this mean in practice? I know about variable hoisting and function scoping, but not about old JS GC algos.

My read was that Internet Explorer couldn’t realize that a string variable could be reused over and over so each iteration of the loop it was allocating a new one, using it, and then garbage collecting it. Basically tons of unnecessary overhead.

Having the programmer define a variable before the loop and then reuse it each iteration meant that all that allocation and garbage collection wasn’t necessary during the passes of the loop.

That is exactly right.

I switched from Flow to TypeScript. Flow has some type-declared libraries, but it's fewer than TypeScript type-declared libraries. The excellence of VSCode also helps me.

> it's likely if you use Google products you've interacted with some TypeScript code

Transpiled Typescript code I expect, so?

So... I love Typescript, but...

"Because TypeScript already mostly works — that's part of the reason to adopt it"... c'mon

I'm still reluctant to use TypeScript given that it has a serious type narrowing bug that is two years old! You'd think Microsoft could have sorted this out by now.


I always wonder why people think typescript is a fix for bad code.

We primarily do JavaScript, and I see no issues with it when you set up governance in how to use it.

I don’t think building your own libraries is really a bad thing either, in fact I think you should do so often instead of relying on 3rd party packages of quality you typically judge on how many times they’ve been downloaded if you’re being honest.

I think typescript is silly. It works with legacy code, sure, but if you’re refactoring you might as well rewrite your JS or if you’re compiling to JS you might as well chose Dart which is vastly superior to typescript.

I don’t really see type safety as an issue. I can’t remember when it was a problem for us, and we operate millions of lines of code, but they are all written with governance. Want a number? Then call your argument numWhatever and check your input. It’s really as easy as that.

I mean, sure type checks will prevent shitty code from compiling, but really, just don’t write shitty code. I know that sounds silly to some people, but 95% of what you write is about shifting data around through simple mechanics, it really shouldn’t be so hard to do it right.

You won’t see an engineer go “oops that support beam in your building wasn’t right, my bad” and programmers really shouldn’t get that luxury either. If they write shitty code then figure out why, maybe they need more time, maybe they need training, maybe they need governance or maybe they need to be replaced.

But hey, feel free to fix your shitty code with code that’s only less shitty because your compiler protects you. Just know that typescript comes with a different set of risks, once you need your JS codebase to move forward in a way that isn’t supported by JS.

How is dart superior to TS? This is so uninformed. Just like your view of what a type system does.

Dart is very poorly designed, and they managed that even without the constraint of being 100% compatible with good old broken javascript.

It doesn't have null safety. This right here, is enough said and yet we could continue for hours, like how its standard library made the same 20 years old mistakes as java with things like "immutable collections are just mutable collections that throw exceptions", etc, etc.

Flutter might increase the demand and pressure on Dart quality but it's not a good language by any stretch of the imagination.

>How is dart superior to TS? This is so uninformed.

Speaking of uninformed...Dart is significantly faster for one. It's also not encumbered by being a superset to one of the worst scripting languages ever designed and, thus, does not have to deal with all of the baggage JavaScript brings with it.

>Dart is very poorly designed.

Amusing when you consider the clusterfuck that is JavaScript.

> fix your shitty code with code that’s only less shitty because your compiler protects you

I mean... Yes? That's exactly what it's for. That's all it's for. That's all I want out of it, and that's what it does. I'm not really sure what you're railing against here.

My point is that I don’t think it fixes your shitty code.

Especially not if you’re not converting your entire project to typescript, and if you’re converting the entirety of it, then why not use a better language?

I think typescript is popular because it’s very java/c# like and I think it’s dangerous because it allows you to write bits of your program with the safety it provides and other bits without it.

So you’ll have programmers thinking they are safe, when they are really not.

TypeScript has structural (not nominal) typing, which makes it very different from Java/C# in practice.

Also, it doesn't fix shitty code. It just lets the compiler warn you when you're either making a mistake or misunderstanding some other part of your code base.

You should really try it before you say it doesn't help.

>I think typescript is popular because it’s very java/c# like

I think at beginning it was mostly used by developers familiar with Microsoft stack (.NET world mostly). But TS was not designed for C# developers, it was designed for JS ones! And I'm super happy it's becoming more and more popular in more "mainstream" frontend community.

I'll just copy my old response to some very old thread that talk about why it not just "a language for C# developers":

" Once sometimes asked me "Isn't Typescript a language for C# developers that don't know JavaScript" It's unfortunate that people think that TS is similar to C# just because it came from Microsoft. Flow language is like 80% similar to TS, but no one says it's similar to C#.

TS is just JS + new features from future JS specification + optional type system. And optional type system is fundamentally different than the one in C#, and it was designed to fit well with JS patterns and idioms (structural vs nominal type system)

If you look at TS code that looks like C#, it's because JS looks like that (classes syntax, classical inheritance, lambda syntax - it's all ES7 (or ES2016/ES2017, or whatever it's called now) "

> just don’t write shitty code

Why do you use a screen to look at your code? Sure it helps you see what you are typing but I mean just don't type wrong to begin with and you don't need a screen to see what you just types! Just focus! Don't write that shitty code so you need a screen to keep it from being shitty.

I'm not trying to be snarky I'm trying to make the point that every single tool we use from a compiler, a type system, unit tests, a monitor... are tools we didn't have from the beginning as programmers. And every time a new tool came, there were always people saying "you don't need those crutches, just do it right instead" (Writing machine code, using punch cards etc). Also, they were always wrong.

> Want a number? Then call your argument numWhatever and check your input. It’s really as easy as that.

It sounds like you have reinvented the Hungarian notation - 15 years after it was phased out?

Typescript is superior for refactoring.


I think it’s inferior because it allows you to rewrite only parts, and unless you convert your entire code base, then you’ll not have type safety. Because the bits that aren’t typescript won’t warn you when you compile.

> Because the bits that aren’t typescript won’t warn you when you compile.

You just wrote exactly why static types are great: you get warnings when you forget to refactor your shitty (sic) JS code.

Typescript will happily check your JavaScript code with “allowJs” compiler flag.

We write all our new code in good ol ES6 flavor of JavaScript and typehint in jsdoc. Typescript as a typechecker serves as very well.

It’s a great incremental adoption strategy.

can you explain how this works ? this is very interesting to us. We have a large react app (created using create-react-app) in ES6 and have been considering adopting TS gradually.

This seems a great first step.

AFAIU, just add typescript to your project or globally then in your project set a tsconfig.json file with the allowJs and esModuleInterop flags set to true. Don’t quote me on this but you can probably leave out most of the rest of the flags besides your source location. For example:

        “compilerOptions”: {
            “allowJs”: true,
            “esModuleInterop”: true
        “include”: [ “src/**/*” ],
        “exclude”: [ “node_modules/**/*” ]
You’ll probably have to tweak that, but I hope it helps.


See https://github.com/Microsoft/TypeScript/wiki/JSDoc-support-i...

Also Google’s puppeteer project is typechecked with tsc and the type info is all in jsdocs


> I think it’s inferior because it allows you to rewrite only parts

That's exactly why it's superior, your project just becomes better step by step without an expensive and complicated full rewrite.

Seconded. I don’t see anything bad with typescript itself, but naive but passionate usage of perceived silver bullets tends to create terrible things. there are many terrible coffeescript/backbone codebases, overwrought usage of redux, etc...

Many of such overcomicated systems come from trying to use the latest coolest thing without thinking about if it improved anything. the tools were never used correctly and the person just moved on, marking JS as a shitty language with a shitty ecosystem.

When there’s always something new on the horizon it’s too easy to assume the previous difficulty was because of the old tool vs taking the time to just learn the tool.

There are many developers who don’t really understand MVC for example and so much pain comes from trying to ham fist a jquery mentality into one.

I agree. If you want a statically typed language, then there are plenty of excellent languages that compile to JavaScript. But making JavaScript "more like Java" has already failed back in the 2000s when ES4 was spec'd. JavaScript isn't the most advanced, beautiful, whatever language. Its point is that it's ubiquitous even beyond browsers. By using language extensions you're tying your code to a particular tool chain such as TS or babel, and are already developing not-quite-JavaScript; you could just as well use a better language in the first place.

I think the problem is that people are abusing JavaScript for large projects when JavaScript's purpose is small-scale DOM manipulation in response to UI events.

> Want a number? Then call your argument numWhatever and check your input.

Oh no, please not the ugly Microsoft naming syntax again... I thought that died a long time ago.

What js in browser is missing is something that golang provided on the server - fast, simple (and more standard) way of writing and executing code, including large code bases.

Typesafety is a small part of it and I’m not sure whether switching or choosing entire dev tooling based on just that is worth it. Just structure your code better and use react prop types and most of type issues go away, in react code bases.

Prop-types is for runtime, TS does static type checking. Prop-types are terribly verbose and only work with React (what about utils files, external libraries, etc?).

Applications are open for YC Winter 2019

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