Пример 1



function area (r) {
  return Math.PI * r * r

}



function area (r) {
  return Math.PI * r * r

}

const result = area("1O")
                  
// @flow

function area (r) {
  return Math.PI * r * r

}

const result = area("1O")
                  ❌ ^^^^ This type is incompatible with number.

Пример 2



function length (value) {
  return value.length
            
}

const result = length(null)
// @flow

function length (value) {
  return value.length
            ❌ ^^^^^^ property cannot be accessed on potentially 
                        null value
}

const result = length(null)
// @flow

function length (value) {
  if (value != null) {
     return value.length
  }
  return 0
}

const result = length(null)
// @flow

function length (value: string): number {
  if (value != null) {
     return value.length
  }
  return 0
}

const result = length(null)

Плюсы

  • Опциональная типизация
  • Код анализатор
  • Тулинг (автокомплит, проверки в runtime, ...)
  • Cамодокументирование
  • Проще поддерживать код
  • Проще рефакторить
  • Мягкий переход на типизацию

P.S это не компилятор

Минусы

  • Менее популярный чем TypeScript
  • Меньше готовых тайпингов (но растёт)
  • OCaml

Five simple examples

// @flow

let username: string = 'boris'

let age: number = 26

let isBoris: boolean = true

let array: number[] = [1, 2, 3.14, 42]

let tuple: [string, number, boolean] = ['foo', 0, true]

let object: {foo: string, bar: number} = {
	foo: 'foo', bar: 0
}

let object: {| foo: string, bar: number |} = {
	foo: 'foo', bar: 0
}

Primitives

// @flow

async function getFriendNames(
  friendIDs: Promise<number[]>,
  getFriendName: (id: number) => Promise<string>,
): Promise<string[]> {
  var ids = await friendIDs;
  var names = await Promise.all(ids.map(getFriendName));
  return names;
}

Promise

// @flow

type GenericObject<T> = { foo: T };

var numberObject: GenericObject<number> = { 
    foo: 0 
};

var stringObject: GenericObject<string> = { 
    foo: "foo" 
};

function reversed<T>(array: T[]): T[] {
  let ret = [];
  let i = array.length;
  while (i--)
    ret.push(array[i]);
  return ret;
}

Generics

// @flow

(1 + 1 : number);

var obj = {
  name: (null: ?string)
};

([1, "a", true]: Array<mixed>).map(x => x);

Typecasts

# foo.js
export type Foo = string;

Import/Export

import type { Foo } from "./foo";
var foo: Foo = "Hello";

Links

Flow

By Egor Yurtaev