JavaScript Type Checking with Flow — Typeof Types

John Au-Yeung
Feb 16 · 3 min read
Photo by Stanley Dai on Unsplash

Flow is a type checker made by Facebook for checking JavaScript data types. It has many built-in data types we can use to annotate the types of variables and function parameters.

In this article, we’ll look at typeof types, which are types that are derived from other values.

The JavaScript Typeof Operator

In JavaScript, the typeof operator is mostly useful for checking the type of primitive values. For example, it works for numbers, booleans, and strings:

typeof 2 === 'number'
typeof true === 'boolean'
typeof 'abc' === 'string'

For objects, it always returns 'object' :

typeof { foo: 'abc' } === 'object'

Flow’s Typeof Operator

Flow’s typeof operator is much more useful. It can be used to return the value of any type.

For example, it can get the type for numbers as follows:

let num = 42;
let num2: typeof num = 3.14;

It’ll fail when we assign values of any other type to it, like the following:

num2 = 'foo';

The benefit of Flow’s typeof operator is that it can also be used for objects. For instance, if we have the following object:

let obj = { foo: 1, bar: true };

Then we can use the typeof operator to assign the obj object as a type of another object as follows:

let obj2: typeof obj = { foo: 1, bar: false };

As long as we have all the properties of obj with the same data type, then it satisfies the requirement of the typeof obj type.

We can do the same for arrays as follows:

let foo = [1, 2, 3];
let bar: typeof foo = [3, 2, 1];

typeof foo will infer that the type of foo is a number array, so we can assign another number array to bar .

Type Inference

The typeof operator does type inference implicitly. When we use literal values with Flow, then the inferred type is the primitive that the value belongs to.

For example, 1 would be a number . We can override the inferred type by explicitly asserting the type of variable we define as follows:

let num1: 1 = 1;

Then assigning num1 to anything other than 1 will fail:

let num2: typeof num1 = 3;

The code above will give us an error.

Photo by Sebastian Pociecha on Unsplash

Typeof’s Nominal Type Check

Like other parts of Flow, the typeof operator also checks type nominally. This means that it checks the name rather than the structure. Therefore, even though 2 types have the same structure, but when their names are different, then they’re considered different.

For example, if we write:

class Foo {
foo(val: number) { }
}
class Bar {
foo(val: number) { }
}

Then the following assignment would work:

let x: typeof Foo = Foo;

because both types have the same name, but:

let y: typeof Foo = Bar;

would fail even though Foo and Bar have the same structure since the have different names.

With Flow’s typeof operator, we can identify types of objects in addition to primitives. It’s consistent with Flow’s nominal type system in that it also checks the name by its name instead of the structure.

Also, the typeof operator can infer types from the data that’s assigned to a variable. For example, if a variable is a number array, then using the typrof operator on that array will return number array as the type.

The Startup

Medium's largest active publication, followed by +611K people. Follow to join our community.

John Au-Yeung

Written by

Web developer. Subscribe to my email list now at http://jauyeung.net/subscribe/ . Follow me on Twitter at https://twitter.com/AuMayeung

The Startup

Medium's largest active publication, followed by +611K people. Follow to join our community.

More From Medium

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade