Open response to “Tests > Types”

TypeScript’s advantages over JavaScript are clear for all.

Adam Terlson
ITNEXT

--

Photo by Brendan Church on Unsplash

What follows is a response I wrote to a developer who had some rather bold claims about typed vs untyped JavaScript applications (and statically vs dynamically typed languages in general).

While I won’t try and reproduce the developer’s argument, the main points were roughly:

  • Any time spent adding types to JavaScript code is better spent writing tests.
  • There is no value that types bring to developing JavaScript applications that cannot be better achieved in some other way.
  • Library authors and the community do not benefit from publishing type definitions with for their libraries.

The first two paragraphs of my letter directly addresses this article which was sent to me as evidence that statically typed languages are not superior to dynamic ones. You can read the article here: https://danluu.com/empirical-pl/.

I hope you might find this open response insightful or helpful. I welcome your thoughts or response!

Hi,

I spent a while reading through the article you sent. The author wrote this piece in response to “strong statements” regarding the absolute superiority of typed languages. The body of the article simply reviews each example used as “evidence” for this claim, disputing each for various reasons.

The article makes the point that there is insufficient scientific evidence for static-typed languages vs dynamically-typed. Accepting this at its face, the conclusion is that one cannot be certain either way. The best position to inhabit is one of unknowing indifference: “Neither is better than the other.” This is perfectly in line with my position — absolute statements about the superiority of static or dynamic languages are unjustifiable.

A false dichotomy

Like any other software engineering tool, types have a potential to add value for our code and the people who develop/maintain it. Claims that “types are inferior to tests” and “any time spent writing types should be spent on more tests” creates a false dichotomy between two tools that are better used and considered in concert with each other. Both have the capability to make our code easier to understand, develop, and maintain. Knowing how/when to leverage both of these tools (and others) in order to maximize these effects, given a specific project and team, is one job of a good software engineer.

High stakes in errors

While it might not be possible to achieve scientific consensus on static vs dynamic languages, I feel that doesn’t prevent one from recognizing the value typed JavaScript (especially TypeScript) has brought to JavaScript app development. I have been writing JavaScript for over many years now, building large apps in large departments and teams. It is perfectly possible to create very large JavaScript applications.

However, it’s also exceptionally challenging to catch all errors (especially from more junior colleagues) before they hit production. Historically that’s been mostly survivable — nothing more than an error in a console somewhere. In the world of React Native or server-side JavaScript, however, an error means your app or server crashes! Preventing this from happening should be the #1 goal of a software engineer and accomplishing it takes expertise and the skillful utilization of every tool the engineer’s disposal, including both tests and types.

TypeScript has made open source better

Looking forward, I will never write another JavaScript app without leveraging or benefitting from TypeScript.

Firstly I will massively benefit from the god-send that are type definitions for all of my dependencies. This simple, zero cost thing objectively makes my application better and my developers more productive, whether I choose to add types to my own JavaScript code or not.

There are no additional costs to my project, but the upsides include better tooling and preventing whole classes of errors (that are difficult or impossible to catch by writing tests, unless you plan to never mock your dependencies). While the author or community may have had to pay the price for writing and maintaining those types, the whole world benefits a million times over for them having done so.

I cannot tell you how much time I’ve wasted over my career paging through documentation (if it exists at all), figuring out a function’s arguments and return values, and catching usage errors at runtime. Eliminating this effort entirely (or at the very least dramatically reducing it) is a real gift TypeScript has brought — and I for one will always choose to take advantage of that.

I intend to provide types to consumers of my JavaScript code, so that they can similarly benefit. Whether this consumer is in the open source community, on my team, or the poor soul debugging my code two years from now — having types can go a long way to understanding, using, and changing large opaque JavaScript codebases.

A more balanced position

I hope you will consider taking a new position: one that recognizes the real benefits typed JavaScript has brought to apps, teams, and the entire community, especially in early error detection, developer productivity, and tooling. Tests are a hammer and types a screw driver — not every problem is a nail nor is every problem a screw — you need to have both tools in your belt. As a software engineer, one needs to know the strengths and weaknesses of every tool at his/her disposal including when/how to use each in different projects/teams.

I hope you will carefully consider the benefits (and costs) choosing typed JavaScript could bring to your future projects.

Adam

--

--

Writer for

A passionate software engineer from the US. Loves building things. Bad at social media.