var foo = "test";
foo = 32;
foo = true;
var bar = foo + 42;
var foobar = (a) => a + "2";
foobar(20);
foobar("test");
foobar = (b) => b;
foobar(bar);
to be
precise and fast
and
sound and complete as possible
var foo = "test";
foo.lenght;
flow defines optional maybe type. With this type you can specify if the value will have user type, null or undefined.
function<T> foo(bar: ?T)
function bar(num: ?number){
return num;
}
bar(5);
bar(null);
bar(undefined);
function bar(num: ?number){
if(num){
return num * 2;
}
}
flow defines object type as similar to JS as possible with some extra features like:
var obj: {foo: string, bar: number} = {foo: "test", bar: 5};
var optional: {foo: string, bar?: number} = {foo: "test"};
var sealed: {foo: string, bar: number} = {foo: "test", bar: 5}; var a: num = sealed.lack;
var unsealed: {}, var unsealed.foo = "test", unsealed.bar = 5;
var exact = (obj: {|foo:number|}) => {...}
exact({foo:5, bar: "test"});
exact({foo: 5});
flow defines class type the same as in JS. The biggest difference is that flow treats classes as nominal type.
class FooClass{
property: number;
constructor(property:number){}
foo(){
this.property;
}
}
var bar: FooClass = new FooClass(5);
class GenericClass<A, B, C>{
propertyA: A;
propertyB: B;
constructor(propertyA: A, propertyB: B){}
foo(): C {
return ...;
}
}
var baz: GenericClass<number, string, boolean>
= new GenericClass(5, "test");
You can define properties in class as writeOnly and readOnly using property variance.
class FooClass{
+bar: number; //read only
-foo: string; //write only
constructor(bar: number, foo: string){}
}
var baz: FooClass = new FooClass(5, "test");
baz.bar = 10;
baz.foo;
type FuncType = (a:string) => void;
function func(a:string) { }
var newFunc:FuncType = func; // it's ok!
type ObjType = {foo: string};
var object = {foo: "test"};
var o:ObjType = object; // it's ok!
class ClassA { foo: string; }
class ClassB { foo: string; }
var c:ClassA = new ClassB(); // error!
Due to its object-oriented and functional nature JavaScript, flow is both nominal and structural typed.
Structural | Nominal |
---|---|
objects | classes |
functions |
In flow you can use several "special" types that can handle some of edge cases:
// MIXED
function foo(x:mixed){
return "" + x;
}
foo(3);
foo("test");
foo(null);
// FUNCTION
function method(func: Function) {
func(1, 2); // Works.
func("1", "2"); // Works.
func({}, []); // Works.
}
method((a:number, b:number) => {});
// ANY
function bar(a:any, b:any): any{
var foo = a;
typeof foo == "number";
typeof foo == "string"
}
bar(3, "test").length