Arrays
Array types are simply instantiations of a special polymorphic Array class:
the type Array<T>
describes arrays whose elements are of type T
. The
shorthand syntax T[]
is equivalent to Array<T>
.
Type Annotating Arrays#
1 2 3 | /* @flow */ var a = [1, 2, 3]; var b: Array<number> = a.map(function(x) { return x + 1; }); |
In this code, we create an array with the literal [1, 2, 3]
, and call a method map on it, getting another array whose type we annotate as Array<number>
.
Array Elements#
Interestingly, the element type of an array is not fixed: it is a supertype of the types of all elements written into the array. Just like other polymorphic classes, array types are invariant in their element types.
For example:
1 2 3 4 5 6 7 8 9 10 11 | /* @flow */ var a = []; for (var i = 0; i < 10; ++i) { if (i % 2 == 0) { a[i] = 0; } else { a[i] = ''; }; } function foo(i): string { return a[i]; } |
Running Flow produces the following error:
example.js:5:14,14: number
This type is incompatible with
example.js:11:18,23: string
The type of a
is not pinned to Array<number>
by the element write a[i] = 0
at line 4: if it did, Flow would report an error for an incompatible element
write a[i] = ''
at line 5. Instead, based on lines 4 and 5, the type of a
becomes Array<T>
where T
is number
or string
. Since it is impossible
to know which element is read on line 11, Flow must account for the possibility
that it could be number
, in which case it would be incompatible with the
string
annotation, as reported.
Exporting Arrays#
When an array is exported, its element type must be specified. This effectively “seals” the element type.
Tuples#
Tuples types represent fixed length JavaScript arrays with known types for each
element. So while the type Array<number>
represents a JavaScript array with unknown
length where each element has the type number
, the type [number, string]
represents
a JavaScript array of length 2 where the first element is a number
and the
second element is a string
.
More generally, given types T0
, T1
, …, Tn
, the tuple type
[T0, T1, ..., Tn]
represents an array of length n + 1
, where the element at
index k
has the type Tk
, assuming 0 <= k <= n
.
Syntax#
Tuples are arrays, so they are declared like array literals
1 | [<type1>, <type2>, <type3>, ...] |
Example#
1 2 3 4 5 | /* @flow */ function mult_first_and_third(tup: [string, number, boolean, number]): number { return tup[1] * tup[3]; } mult_first_and_third(["1", 1, true, "positive"]) |
5: mult_first_and_third(["1", 1, true, "positive"])
^ string. This type is incompatible with
2: function mult_first_and_third(tup: [string, number, boolean, number]): number {
^ number
Found 1 errors
Arity#
The arity (i.e. length) of a tuple is strictly enforced, so that Flow can be
relatively confident that a tuple of length N
is actually an array with length
N
. This has a few consequences.
An Array<T>
type cannot flow to a tuple, since we don’t know the array’s
length
1 2 3 | function array_to_tuple(arr: Array<number>): [number, number] { return arr; } |
2: return arr;
^ array type. Only tuples and array literals with known elements can flow to
1: function array_to_tuple(arr: Array<number>): [number, number] {
^ tuple type
Found 1 errors
You cannot use Array.prototype
methods that mutate the tuple
1 2 3 4 | function mutate_tuple(tup: [number]): void { const str = tup.join(', '); // OK tup.push(123); // Error } |
3: tup.push(123); // Error
^ property `push`. Property not found in
3: tup.push(123); // Error
^ $ReadOnlyArray
Found 1 errors
A tuple type cannot flow to an Array<T>
type, since then you could mutate the
tuple in an unsafe way.
1 2 3 | function tuple_to_array(tup: [number]): Array<number> { return tup; } |
2: return tup;
^ tuple type. This type is incompatible with the expected return type of
1: function tuple_to_array(tup: [number]): Array<number> {
^ array type
Found 1 errors
A tuple type cannot flow to a longer tuple type.
1 2 3 | function short_to_long(tup: [number]): [number, void] { return tup; } |
2: return tup;
^ tuple type. Tuple arity mismatch. This tuple has 1 elements and cannot flow to the 2 elements of
1: function short_to_long(tup: [number]): [number, void] {
^ tuple type
Found 1 errors
A tuple type cannot flow to a shorter tuple type.
1 2 3 | function long_to_short(tup: [number, number]): [number] { return tup; } |
2: return tup;
^ tuple type. Tuple arity mismatch. This tuple has 2 elements and cannot flow to the 1 elements of
1: function long_to_short(tup: [number, number]): [number] {
^ tuple type
Found 1 errors
You can edit this page on GitHub and send us a pull request!