Engineering
Why the World Is Adopting TypeScript
TypeScript has tipped.
In the last few years, TypeScript’s adoption has exploded. It has become the language of choice for companies building large, dynamic single-page applications that replace desktop software. It was created and is maintained by Microsoft, and it’s by far the most successful language that compiles into JavaScript.
For many engineering teams, the idea of introducing TypeScript feels unnecessary, or like a waste of engineering resources. Why go through all that effort to add another layer of complexity to your web app? Why learn a statically typed language when JavaScript has served you well for so many years?
Typed languages are better for scaling
Large engineering teams write and maintain hundreds of thousands of lines of code, and typed languages provide the safety needed to keep large teams productive while also reducing stagnation from fear of breaking production code.
In the past, dynamic programming languages have had to evolve to meet the needs of large engineering teams. A new breed of tools and languages are being developed to allow engineers to introduce types into codebases written in dynamic languages.
Last year, Stripe felt the pain of a massive codebase written in Ruby, a dynamic language. So Stripe built Sorbet, a static type checker for Ruby. Sorbet is incrementally adoptable — engineers can write new code that is type checked with Sorbet, enjoying the benefits of a statically typed language but without being forced to change older code until it makes sense to do so. Sorbet has been a big success for Stripe, reducing errors in production and increasing productivity.
Similarly, with a large, successful product and a growing codebase, Python was causing similar issues for Dropbox that Stripe faced with Ruby. Dropbox adopted mypy for 4 million lines of Python, an incrementally adoptable static type checker for Python.
Seeing a pattern? Enter TypeScript: a statically typed superset of JavaScript that is incrementally adoptable.
How do types help you scale?
Types can help you scale in three ways: eliminating bugs, documenting the codebase, and enabling engineers to write code faster.
- Eliminating Bugs: Static types eliminate one of the most common bugs we see in production software: method not found. Typos, dynamic memory allocation, scope issues, asynchronicity, and more can cause this fundamental kind of bug. Types, when applied properly, can all but eliminate runtime errors of this kind.
- Documenting the Codebase: Types are documentation for mundane things you’d never want to document. Having to define the expected result from a relatively complex map-reduce operation may feel tedious in the moment, but it’ll save anyone else coming up to speed in your codebase an immense amount of time. Without documentation around these micro data structures, engineers have to hold hundreds of bits of information like this in their head to write just a few lines of code.
- Enabling Engineers: Type checkers run inside your editor. In stark contrast to tests, which often take a long time to run, type checking happens continuously. Programmers are given guidance as they type in the form of context-aware autocompletion. Most errors are shown the second they are coded. The old adage that a bug takes longer to fix the later it’s found holds true even for the minute timescale of the text editor to the browser. Having to find out you just wrote 40 lines of code on an incorrect assumption about a method argument adds up.
TypeScript can be frustrating to learn
If you come from a JavaScript background, TypeScript is just similar enough to be frustrating. It’s hard to tell where regular JavaScript ends and TypeScript begins.
TypeScript is a superset of JavaScript, so it inherits the idiosyncrasies of a language that has had to evolve to meet the needs of the web. This was a conscious decision made by the language designers, and it’s part of the reason for TypeScript’s success. TypeScript doesn’t attempt to gloss over these idiosyncrasies, which makes it easier to adopt while still providing many benefits.
When you first get started with TypeScript, you’ll feel less productive. Before you give up on TypeScript, keep these two things in mind:
- TypeScript errors are meant for your editor, not the command line. You need to see the exact line and symbol that’s affected by a TypeScript error to fix it. Unlike JavaScript errors in the browser, type errors happen granularly and frequently. Thankfully, because TypeScript is so popular, all major editors have TypeScript support. Enabling editor support is critical for productivity, so we recommend all users add TypeScript support in their editor on day one.
- TypeScript is about fixing errors for the developer, not the user. Types make certain things more difficult and verbose to accomplish, such as polymorphism and inheritance. This isn’t a bad thing. If it’s difficult to do it in TypeScript, it will also be difficult to read and reason about. Restrictions like these can be frustrating for experienced JavaScript programmers who are used to dynamic behaviors defined at runtime.
Powerful possibilities…
There are rewards! Here are six incredible things you can do once your team adopts TypeScript:
#1: Generate types from your API endpoints and use them directly in your frontend code. Find out about breaking API changes at build time, making it impossible to deploy incompatible code for your users. You can manually create types using quicktype’s browser-based type generator, or if you’re lucky enough to have a GraphQL backend, generate types and queries with GraphQL Code Generator automatically.
#2: Refactor hundreds of files without fear. Because each line of TypeScript explicitly defines its behavior, changing a large amount of files in a codebase can be done with confidence and zero errors. It’s like having unit tests for every file in your codebase.
#3: Learn a new library by just npm installing it and searching for method names and reading pop-up documentation in your editor. Giant API-driven companies like Slack and Stripe are shipping first-party TypeScript support for their client libraries.
#4: You’ll write more concise and readable code. Eventually, once you stop fighting with the basics of TypeScript, you’ll learn to write better code. If code is difficult to type properly, it’s difficult to read and more likely to cause bugs.
#5: Write code for 20 minutes without leaving your editor (and if you’re a Vim user, no mouse). I’m still shocked every time my code works on first try in the browser. Because you can see errors early and often, TypeScript lowers the pain of the write, save, refresh workflow that web developers rely on so heavily.
#6: You can stop writing unit tests for all but the most complex parts of your codebase. Type safety covers the vast set of errors you’re likely to make handling data. Focus on the tests that matter for your app.
TypeScript is the future
Using TypeScript is how we stop dealing with mundane errors and build more complex apps that we can actually maintain. Yes, there’s a learning curve, but it’s necessary for us to move the state of the art of web applications forward. So if you’re unsure, bite the bullet and try adopting TypeScript for a few new files in your codebase or for your next project.
Aaron Ortbals is a Partner and Director of Engineering at Postlight. Jeremy Mack is a Managing Partner and Director of Engineering at Postlight. Interested in working with Postlight Engineering? Get in touch: hello@postlight.com.
Story published on Oct 13, 2020.