JavaScript Static Type Checkers

October 28, 2019 • ☕️ 3 min read

JavaScript is a dynamic typed language, community wants to bring benefits of static typed languages into it by creating static type checkers for it. Let’s figure out what static type checker is and what options do we have.

Static Type Checker

JavaScript only supports dynamic type checking, which means type safety is only verified at runtime; it brings the flexibility to the language but allows unexpected errors at runtime.

Static type checking is the process of checking type safety based on source code. It offers some awesome benefits like caching errors early, limiting type errors, supporting auto-completion, generating documentation, and resulting faster compilation.

A number of useful and common programming language features cannot be checked statically, such as downcasting. Thus, many languages will have both static and dynamic type checking; the static type checker verifies what it can, and dynamic checks verify the rest.

Static type checker comes with a type system and provides the backbone needed for many useful IDE features such as error highlighting, autocomplete, and automated refactoring.

Static type checker helps developer write code with fewer bugs by adding types to your code, trying to catch type errors within your code, and then remove them during compile time.

There are two popular static type checkers for JavaScript are Flow and TypeScript.

Flow

Flow is a static type checker for JavaScript, written in OCaml, developed at Facebook, super easy to setup in an existing codebase. It supports type system, type annotations, library definitions, linting and many more.

Following Flow documentation to add Flow into your project, making sure Flow syntax will be stripped from compiled code, and migrating to Flow at your own speed, manually run commands to analyse your code and generate insightful information.

Flow can automatically infer type information from existing code by using a technique they called flow analysis, and pick up any type errors by itself.

Flow is incrementally adoptable and it can be easily added and removed from our code base without breaking anything, it good in case we only want to enable type checking for only one part of our project.

// @flow
function square(n: number): number {
  return n * n
}

square('2') // Error!

TypeScript

TypeScript is not actually a static type check but can be used as one. It is a programming language developed by Microsoft, is a typed superset of JavaScript, compiled to plain JavaScript in the end. Major text editors and IDEs have built-in support for TypeScript.

With the goal of strengthening the JavaScript language to make large-scale application development easier, TypeScript integrates many modern programming features such as module, class and interface into the language.

Optional type system — you use type annotations at your own speed; the more you use, the more benefits you get from static type checking.

Use latest JavaScript features — TypeScript comes with its own compiler and compiled to JavaScript in the end, so you can use any new latest features of JavaScript bundled along with compiler without additional tools like Babel.

Great community support — has awesome community and tooling system backed by Microsoft.

Great browser compatibility — the compiler does some magic to transform your code into ES5-compliant JavaScript makes it compatible with all modern browsers.

TypeScript has great support in all major text editors and IDEs, making your life easier with code completion and type inferences.

const add = (x: number, y: number) => {
  return x + y
}

class Drawer<ClothingType> {
  contents: ClothingType[] = []

  add(object: ClothingType) {
    this.contents.push(object)
  }

  remove() {
    return this.contents.pop()
  }
}

Conclusions

Using a static type checker for Javascript can greatly improve the safety of your code, but it does comes with drawbacks like big investment on learning, increasing the verbosity of your code, or slowing you down.

Flow and TypeScript have their own strengths and weaknesses. TypeScript is getting more and more popular when many companies and open source projects are migrating into it.

One thing that Flow can do but TypeScript cannot is the ability to take advantage of the static type checking functionalities without the need to write non-standard JavaScript code.

If you’re working on a large project that’s built to last, using static type checker is almost certainly a good idea. On the other hand, if you’re just throwing together a small weekend project, it’s probably safe to skip static typing.

And finally, I think that both Flow and TypeScript have reached a stage where they are totally valuable to use. It’s a matter of preferences and what works for you might not work for me.