Google Developer Rips 'Painful' TypeScript 3.5 Upgrade

A GitHub issue titled "Google feedback on TypeScript 3.5" rips the "painful" release for causing upgrade problems across Google's repository of billions of lines of code.

TypeScript, an open source project created by Microsoft before being donated to the community, has reached new levels of popularity stemming from JavaScript-related advancements that provide for optional static typing, among others.

Although any changes to the language cause the Google team to rework its massive codebase, Google developer Evan Martin pointed out three changes in the TypeScript 3.5 release that made it "especially painful," including one that "broke our code everywhere."

While emphasizing that Google was "very happy with TypeScript in general," Martin said:

We believe most of these changes were intentional and intended to improve type checking, but we also believe the TypeScript team understands that type checking is always just a tradeoff between safety and ergonomics.

It is our hope that this report about TS 3.5 as applied to a large codebase will help the TypeScript team better evaluate future situations that are similar, and we make some recommendations.

Martin, who has recently presented on Google's use of TypeScript, detailed the three main problems with the upgrade and offered suggestions to alleviate each. Summarized, they are:

  • Implicit default for generics: "This was the headline breaking change in 3.5. We agree with the end goal of this change, and understand that it will shake up user code.

    "Historically when TypeScript has introduced type system changes like this, they were behind a flag.

    "Suggestion: Using a flag here would have allowed us to adapt to this change separately from the other breaking changes in 3.5."

  • filter(Boolean): "TypeScript 3.5 changed the type of the Boolean function, which coerces a value to boolean, from (effectively)

    function Boolean(value?: any): boolean;
    function Boolean<T>(value?: T): boolean;
    While the rest of the comment is too verbose and technical to summarize here, Martin suggested: "A more sophisticated definition of Boolean, one that removed null|undefined from its generic, might have helped, but from our experiments in this area there are further surprises (search for 'backwards' on the above RxJS bug). This was also not mentioned in the list of breaking changes in 3.5. It's possible its impact was underestimated because it disproportionately affects RxJS (and Angular) users."

  • Set: "In TypeScript 3.4,

    const s = new Set();
    gave you back a Set<any>. (It's actually a kind of amusing type, because in some sense almost everything still works as expected -- you can put stuff in the set, .has() will tell you whether something is in the set, and so on. I suspect this might be why nobody noticed.)

    "TypeScript 3.5 made a change in lib.es2015.iterable.d.ts that had the effect of removing the any, and the generic change described above made it now infer unknown.

    "This change ended up being tedious to fix, because the eventual type errors sometimes were pretty far from the actual problem."

    Martin's suggestion reads: "We are surprised nobody noticed this, since it broke our code everywhere. The only thing worth calling out here is that it seems like nobody made this change intentionally -- it's not in the breaking changes page, and the bug I filed about it seems to mostly have prompted confusion. The actual change that I think changed what overloads got picked looks harmless. Perhaps the main lesson we learned here is that we needed to discover this earlier and provide this feedback earlier."

A project contributor with the handle AnyhowStep responded to the post, in part saying, "A good workaround for most of these problems is to just have a lint rule to always explicitly specify type params for certain constructors/functions."

The issue garnered some 70 comments on Hacker News, where Martin's comment about some TypeScript code "relying on inference too much" was discussed in the top post.

Several Hacker News comments expressed "love" and admiration for TypeScript, and Martin's GitHub post also said: "I'd like to emphasize we are very happy with TypeScript in general. It is our hope that the above critical feedback is useful to you in your design process for future development of TypeScript."

TypeScript 3.5 was released in May. Coincidentally, Martin's Sept. 5 post came about a week after TypeScript 3.6 was introduced by program manager Daniel Rosenwasser.

Rosenwasser was "assigned" to the GitHub issue four days ago but that assignment was subsequently removed and the issue was tagged as "discussion," and the "Meta-Issue" and "Planning" labels were removed, so apparently no official action will be taken in regard to the post.

Martin's post (which garnered more than 400 approval icons) included a final note to Rosenwasser: "@DanielRosenwasser if you or anyone on your team who was interested read this, feel free to close it; I don't think it's actionable as a bug. (Also lemme know if it was useful or not, and we can do a similar one for 3.6.)"

At press time, developers were still commenting on the post.

Update: After this article was originally published, Rosenwasser answered Martin directly:

Hey @evmar, thanks a ton for writing this up. Having this available publicly is great, and gives us an easy way to return to this discussion, so I especially appreciate that. It sounds like users outside of both Google and Microsoft have gotten something out of it too!

This isn't the first batch of feedback that we've leveraged either. For example, with certain breaks, we've tried to stretch them out over several releases. But for what it's worth, I think that getting this sort of feedback earlier on would be more ideal since we would have realized how impactful each of these changes were (and whether they warranted a flag). While we can err on the side of caution and always introduce flags and the like, that's still more cognitive overhead we'd generally rather avoid.

We've actually expanded our release cadence in 3.6 to be longer in order to encourage users (and larger organizations like Google) to have more time to upgrade and try betas and RCs. I think that the sooner you can upgrade to 3.6 and hopefully the 3.7 beta, the better off the community as a whole will be too. Let us know if there's anything we can do to help there!

About the Author

David Ramel is an editor and writer for Converge360.

comments powered by Disqus


Subscribe on YouTube