Categories
Flow JavaScript

JavaScript Type Checking with Flow — Intersection Types

Spread the love

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 piece, we’ll look at how to use intersection types to create variables that accept a combination of multiple types.


Defining Intersection Types

We can create intersection types by separating multiple types with an & sign as follows:

Type1 & Type2 & ... & TypeN

We can also break the expression above into multiple lines with the leading & sign:

type Bar =  
  & Type1  
  & Type2  
  & ...  
  & TypeN

Also, we can create intersection types from other intersection types:

type A = Type1 & Type2;  
type B = Type3 & Type4;  
  
type Foo = A & B;

Properties of Intersection Types

When we call a function that accepts an intersection type, we must pass in data that has all of those types. But inside the function, we can treat them as being one of the types in the intersection type.

For example, if we define the following function:

type A = { a: number };  
type B = { b: boolean };  
type C = { c: string };  
  
function foo(value: A & B & C) {  
    
}

Then we can treat value as having to be any one of A , B and C, as follows:

function foo(value: A & B & C) {  
  let a: A = value;  
  let b: B = value;  
  let c: C = value;    
}

Impossible Intersection Types

We can create intersection types that are impossible. For example, we can create a type that’s an intersection of string and boolean, as follows:

type StringBoolean = string & boolean;

This type is useless since no value can be both a string and a boolean, so we can’t assign anything to it.


Intersections of Object Types

An intersection of object types means that an object of the intersection type must have all the properties of both types.

For example, suppose we have the following intersection type:

type Foo = { foo: string };  
type Bar = { bar: boolean };
type FooBar = Foo & Bar;

The variable that we create of type FooBar must have all the properties of both Foo and Bar:

let foobar : FooBar = {  
  foo: 'abc',  
  bar: true  
};

When two object types have the same property name but a different type, then when they’re intersected together, the new property with the same name will have the intersection of both types as the new type.

For example, suppose we have:

type Foo = { foo: string };  
type Bar = { foo: boolean };
type FooBar = Foo & Bar;

Then foo will have the string & boolean intersection type, which means that no value can be set to it.

With intersection types, we can create types that have all the properties of each type that form the intersection type. We can also create intersection types from primitive types, but they’re useless since nothing can be assigned to variables of those types.

This means that intersection types are useful for object types mostly.

Leave a Reply

Your email address will not be published. Required fields are marked *