The FullScreenMario project burned brightly for a few short weeks in October 2013 after Boing Boing lauded it as “a pretty impressive example of what HTML5, in-browser functionality can do.” A few days later, it went viral on Reddit and by November, attention turned to scrutiny, and Nintendo took the project down with a DMCA request.
”I had no sense of when values would be initialized or what odd interactions they'd have,” he says. “Bugs would frequently pop up because I'd use something before it was initialized, or in the wrong way, or just in a way that I hadn't designed it for.”
Types (short for “data types”) are descriptions of what sort of data a variable contains—for example,
“Scripting languages are great for small programs, but a program with millions of lines of code that a large number of developers will collaborate on needs better encapsulation and modularity,” explains Amanda Silver, who was a Group Program Manager on the original TypeScript team, and now leads product for Microsoft’s Developer Division overseeing developer tools, runtimes, and services like Visual Studio Code, .NET, C#, TypeScript, and Azure’s Developer Experience.
Goldberg took advantage of TypeScript’s static qualities when he later refactored FullScreenMario into EightBittr, a game engine for 2D 8-bit games. It was pretty much TypeScript from there on out for him, and he isn’t alone.
TypeScript was the third fastest-growing and fourth most-used language in GitHub’s Octoverse 2022 report. RedMonk puts it at number eight on its top 20 languages list, jumping up from 17 in 2017. Stack Overflow has it as the fourth most-loved and third most-wanted language in its 2022 Developer Survey.
“We developed TypeScript to help programming at scale, but it really wins at almost every level of development,” says Daniel Rosenwasser, the current Product Manager on TypeScript. “TypeScript really proved out a lot of what works and what’s possible for existing dynamic languages, and has gotten a lot of love. Now each of those languages has different challenges, but often there’s something they can take away from that.”
But this isn’t a zero-sum game. The story of TypeScript, and the recent paradigm shift of the past decade, is less about “either or” and more about getting the best of both worlds—with gradual typing. In fact, while Python is still dynamic, it too has made the move toward gradual typing, as have several other languages of its ilk.
The pendulum swing of programming language paradigms
Starting with FORTRAN and COBOL in the 1950s and continuing into the 1990s with languages like C++, Delphi, and Java, statically-typed languages dominated commercial software development because of their ability to scale. They could be difficult to learn and slow to use, but waterfall development practices and desktop software released on physical media meant that velocity wasn’t a top concern, safety was. Release timelines were measured in months not minutes, so static languages, alongside extensive testing, helped developers catch bugs before they couldn’t be fixed.
Rosenwasser points to the rich editing experience popularized by TypeScript and VS Code as something often overlooked. “People often get caught up in the type system itself, but there’s so much more that we’ve also built on top of that. People who get a taste of what a great editing experience is like never want to go back,” he says.
“Static typing can codify much of the systemic and institutional knowledge needed to maintain applications of a certain size and complexity,” says Samp. “Mission-critical parts of information that must adhere to specific assumptions can be encoded in the code, rather than relying on comments or tests that may become outdated.”
“Type systems provide a benefit, that's objective. But the over-reliance on type systems is a crutch. Many people think that because they write types, they don't have to write runtime type checks, or tests, and they’re wrong,” says Harband. “A type system is a faster feedback loop that you could get 30 seconds later by running the tests on the command line. With types you get that inline with autocomplete. That's great, but it's not a valuable trade off for having your code be less robust and less correct.”
While TypeScript may not be adequate for Meta’s overall purposes, its popularity indicates that it strikes a balance that developers prefer over Flow’s strictness. In fact, even Meta’s own developers sometimes choose TypeScript. Jest started its move to TypeScript in 2019, Yarn announced its migration in 2020, and React Native just made TypeScript the default for new templates earlier this year.
“Developers love dynamism, but they also want safety at scale,” says Zacher. “But if you go all the way to the other end, to a completely strict system like Flow, they feel too restricted.”
The dawning of the age of gradual type systems
Programming language paradigms are often represented and discussed in terms of binaries, but the reality is that they exist on numerous spectrums. TypeScript’s relative unsafety compared to something like Flow might be seen as a feature by some, but as a bug by others.
“TypeScript proved that it’s best to not swing the pendulum in one direction or the other, but to recognize that it's all the same ecosystem,” says Silver.
TypeScript’s 2012 launch may not have been the spark that lit the fire, but rather the first flames from the embers below. By 2014, TypeScript hit 1.0 and Facebook declared the end of its “move fast and break things” era with the release of Flow, alongside Hack, a language that brought static typing to PHP. By 2015, PHP and Python both added type features, and Sorbet brought types to Ruby the following year. Ruby itself hopped aboard the gradually-typed train in 2021 with RBS, its native type checker. Elixir, a dynamic language released in 2012, recently jumped on board when the language’s creator announced they were researching and developing a type system. And we’ve even seen some examples from the opposite end of the spectrum: C# added gradual typing with a dynamic type in C# 4.0, and Go recently added generics after years of debate.
Many of these projects influence each other. For example, Rosenwasser says the Typescript team, the Python team, and the team behind the Python type checker Pyright are in communication and exchange ideas.
“If adoption required going all-in from the beginning, it would be an unreasonable workflow for most teams,” explains Samp. “Being able to say which parts of the type system are important or not important is really powerful, because it allows teams to focus on important tasks and gradually increase their standards over time.”
In TypeScript, developers can opt into typing on a variable-by-variable basis. If a variable has no declared type, TypeScript will try to infer the type by how it is used. If it can’t determine the type from the context, it will assign the
any type to the variable, which essentially turns off TypeScript's strict type-checking for that variable. From there, JSDocTypeScript can be made progressively stricter using compiler options that broadly enforce static type checking rules, including a strict mode that turns them all on.
Even for fans of TypeScript, though, there’s just one problem remaining that they don’t want to deal with—the build step and the tooling that comes with it.
“The big thing that people really love about dynamic languages is there’s no compilation. You don't have to worry about managing build tools and weird tool chains,” says Zacher. “The developer experience you get from that is amazing, because there's no waiting when you've finished writing your code.”
Can we finally kill the build step?
In 2020, Gil Tayar, now a developer at Microsoft working on the Kusto Query Language (and with no TypeScript affiliation), wrote a blog post describing this process titled JSDoc typings: all the benefits of TypeScript, with none of the drawbacks. While he does concede a few potential downsides, such as verbosity and types bloating your code since they're not removed during the transpilation step, he says that these minor inconveniences are ultimately worth it, just to remove that step.
“I hate transpilation with a vengeance,” he says.
Harband, a TC39 member since 2014, remains unconvinced.
Tayar’s proposal argues that, much like gradual types, it isn’t a zero-sum game.
After nearly a year and a half, the proposal remains at the first of four maturity stages in TC39’s process for changing the ECMAScript specification and recent discussions show that the proposal is young and the committee is far from consensus.
“I think we're going to have much more self-healing programs going forward,” she says. “We're going to be able to provide more and more AI-driven guidance to help users understand where their program is off and how to fix it.”
Samp says she’s already seen the first effects of AI on dealing with types—even just gradual types.
“GitHub Copilot is really good at generating Sorbet signatures. They can be a blocker for people, because they don’t want to have to do that for every single method. The fact that AI can do that for you really boosts the effectiveness of a gradual type system in a dynamic language, which is so, so cool,” she says.