When you are declaring a new variable, you may optionally declare its type.
JavaScript has three ways of declaring local variables:
var
- declares a variable, optionally assigning a value. (MDN)let
- declares a block-scoped variable, optionally assigning a value. (MDN)const
- declares a block-scoped variable, assigning a value that cannot be re-assigned. (MDN)In Flow these fall into two groups:
let
and var
- variables that can be reassigned.const
- variables that cannot be reassigned.var varVariable = 1; let letVariable = 1; const constVariable = 1; varVariable = 2; // Works! letVariable = 2; // Works! // $ExpectError constVariable = 2; // Error!
const
Since a const
variable cannot be re-assigned at a later time it is fairly simple.
Flow can either infer the type from the value you are assigning to it or you can provide it with a type.
// @flow const foo /* : number */ = 1; const bar: number = 2;
var
and let
Since var
and let
can be re-assigned, there’s a few more rules you’ll need to know about.
Similar to const
, Flow can either infer the type from the value you are assigning to it or you can provide it with a type:
// @flow var fooVar /* : number */ = 1; let fooLet /* : number */ = 1; var barVar: number = 2; let barLet: number = 2;
When you provide a type, you will be able to re-assign the value, but it must always be of a compatible type.
// @flow let foo: number = 1; foo = 2; // Works! // $ExpectError foo = "3"; // Error!
When you do not provide a type, the inferred type will do one of two things if you re-assign it.
By default when you re-assign a variable, Flow will give it the type of all possible assignments.
let foo = 42; if (Math.random()) foo = true; if (Math.random()) foo = "hello"; let isOneOf: number | boolean | string = foo; // Works!
Sometimes Flow is able to figure out (with certainty) the type of a variable after re-assignment. In that case, Flow will give it the known type.
// @flow let foo = 42; let isNumber: number = foo; // Works! foo = true; let isBoolean: boolean = foo; // Works! foo = "hello"; let isString: string = foo; // Works!
If statements, functions, and other conditionally run code can all prevent Flow from being able to figure out precisely what a type will be.
// @flow let foo = 42; function mutate() { foo = true; foo = "hello"; } mutate(); // $ExpectError let isString: string = foo; // Error!
As Flow gets smarter and smarter there should be less of these scenarios.
© 2013–present Facebook Inc.
Licensed under the MIT License.
https://flow.org/en/docs/types/variables