All PostsJuly 15, 2020

The Irony of TypeScript and React

React proves libraries don't have to be written in TypeScript to be good at TypeScript.

AuthorBraden Snell

Angular. Ember. Svelte. Vue. TypeScript has been adopted by frontend frameworks with crushing inevitability. The ubiquitous (and often annoying) "Port this to TypeScript" GitHub issues, found in popular JavaScript repositories far and wide, reflect a real desire. Developers want the tooling benefits TypeScript-typed dependencies bring to their codebase. Not every library author has accepted the need to use TypeScript, but most have and more will. The notable exception to this emerging consensus is React, and the notable irony of this notable exception is the unmatched quality of React's TypeScript developer experience.


JSX was introduced to the world in 2013, when React was open-sourced. JSX takes code like this:

const element = <h1 id="hello">Hello</h1>;

And turns it into this:

const element = React.createElement("h1", { id: "hello" }, "Hello");

Its simple syntactic sugar for JavaScript. Anytime anything complex needs to be done developers must hop out of JSX land with a couple curly brackets {} and insert a JavaScript expression. Its simplicity and heavy reliance on JavaScript sets JSX apart. It also gives JSX a distinct advantage: tooling.

In 2015, TypeScript 1.6 was released and support for JSX was added to the compiler. With this release new possibilities ranging from statically validating props, to multi-file component symbol renaming, were given to TypeScript/React projects. By virtue of the close relationship between JSX and JavaScript, feature-rich tooling was relatively easy to add. Other view-describing languages have struggled to meet the bar set by TypeScript and JSX. Even Angular 2, which was written in TypeScript for TypeScript users, falls far short of React's JSX powered TypeScript experience.

The Challenge

The challenge TypeScript poses to library authors today isn't about converting an existing codebase to TypeScript. Instead the challenge is designing APIs that are statically analyzable. The custom template languages common in frontend frameworks today are an extreme example of APIs that are not easy to statically analyze, but they are far from the only example. There are libraries in the JavaScript ecosystem that (barring fundamental API changes) will likely never have great TypeScript support. TypeScript's complex brew of union types, mapped types, conditional types, and variadic types does make many patterns possible to express. Possible, however, doesn't always mean easy.

Clearly, the solution is not to simply (re)write a library in TypeScript, though that certainly helps. The path forward is difficult because it means accepting new limitations. An API with no type-safety requirements will always have more flexibility than one with type-safety requirements. But, constraints are good for innovation. Embracing the limitations TypeScript imposes often leads to the creation of far more simple APIs.

It's Ironic

Typically, a mess of complex generics is a bad idea in application code. For library code, however, the pain is generally worth the effort. Many times TypeScript support is an unasked-for burden placed upon folks building open source software in the JavaScript ecosystem. Welcome or not though, these requests reflect reality. In the end those libraries that embrace and conquer the challenges TypeScript offers will find success. Those that do not, will not reach their full potential. If you're building a new library in TypeScript, or converting an existing one to TypeScript you may wonder where to begin. Perhaps, start by thinking about the ironic truth React teaches us: libraries don't have to be written in TypeScript to be good at TypeScript.

Type Routebeta
Type safe, client-side routing. Harness the chaos of the URL with confidence and flexibility.
Type APIplanned
Full stack type safety. Integrated client/server solution. Generated API docs. Opinionated error handling.
See More
View the full suite of open source Type Hero tools on GitHub.

Join the Type Hero Newsletter

Get the latest Type Hero updates delivered straight to your inbox.

    Powered By ConvertKit