Skip to content
📝 Notes on using and understanding Flow
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github/ISSUE_TEMPLATE
advanced
basics
react
LICENSE
README.md

README.md

Flow Notes

📝 Notes on using and understanding Flow, starting from version 0.85.

🚧 This repo is a work in progress.

Basics

https://flow.org/en/docs/lang/

Objects

https://flow.org/en/docs/types/objects/

Familiar yourself with objects by reading the docs. It covers such questions as

Examples (Flow Try)

type Name =
  | "Simba"
  | "Mufasa"
  | "Nala"
  | "Sarabi"
  | "Sarafina"
  | "Scar"
  | "Kiara"
  | "Kovu"
  | "Vitani";

const GENDER = {
  MALE: "male",
  FEMALE: "female"
};

const purrs = {
  brief: "prr",
  normal: "prrr",
  long: "prrrrr",
  insane: "prrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"
};

type Kitten = {| // recommend using sealed and exact objects

  /** basic fields */
  
  name1: string,
  name2: // disjoint union for more refined typing
    | "Simba"
    | "Mufasa"
    | "Nala"
    | "Sarabi"
    | "Sarafina"
    | "Scar"
    | "Kiara"
    | "Kovu"
    | "Vitani",
  name3: Name, // type alias for easier reuse and readability
  
  age: number,
  
  gender: $Values<typeof GENDER>, // 'male' | 'female'
  
  purrs: $Keys<typeof purrs>, // 'brief' | 'normal' | 'long' | 'insane'

  /** function fields */
  
  purr1: Function, // not recommended because Function is now aliased to `any`
  purr2: () => {}, // likely a typo, did you mean () => void?

  purr3: () => void, // (very common) a function that doesn't take nor return anything
  purr4: string => void, // (very common)
  purr5: (name: string) => boolean, // (very common) use named parameter for better readability

  /** object fields */
  mane1: Object, // not recommended
  mane2: {}, // not recommended: not even sealed, nearly the same as any
  mane3?: { // optional field, meaning this field may or may not exist
    [key: string]: any // can be a last resort if you really don't know what's going on
  },
  
  mane4: ?{ // nullable, meaning this field can be null or undefined
    color: string, // (very common) with defined properties
    type: "mane" | "beard" | "mustache"
  },
  
  manes?: ?({ // fields can be both optional and nullable
    color: string,
    type: "mane" | "beard" | "mustache"
  }[]) // array of objects
|};

const kitten: Kitten = {
  name1: 'kitten',
  name2: 'Simba',
  name3: 'Nala',
  age: 7,
  gender: 'male', // note that this type is widened
  purrs: 'brief', // must be one of the literals
  purr1: () => { console.log('prr') },
  purr2: () => ({}),
  purr3: () => { console.log('prr') },
  purr4: name => { console.log(name + ', prrrrr') },
  purr5: name => !!name,
  mane1: {},
  mane2: {},
  mane3: { color: 'darkbrown' },
  mane4: { color: 'darkbrown', type: 'beard' },
  manes: [{ color: 'darkbrown', type: 'mustache' }]
};

Functions

https://flow.org/en/docs/types/functions/

The docs cover basics of functions such as:

Examples (Flow Try)

/** functions with no parameters nor returns */

function purr1(): void {  // function declaration
  console.log('purr');
}
const purr2 = (): void => {  // arrow function
  console.log('purr');
}
type PurrA = () => void;
const purr3: PurrA = () => {
  console.log('purr');
}

/** functions with parameters and / or returns */

function purr4(name: string): string {
  return 'hello, ' + name;
}

const purr5 = (name: string): string => {
  return 'hello, ' + name;
}

type PurrB = string => string;  // you may optionally leave out parameter names
const purr6:PurrB = name => 'hello, ' + name;

/** polymorphic functions / generics */
function purrAt<T: { name: string }>(creature: T): string {
  return 'hello, ' + creature.name;
}

purrAt({ namee: 'uhuh' }); // sticky keyboard error

/** functions with statics */

type PurrMemo = {
  cachedName: string,
  [[call]](name: string): string, // callable signature
}
const purrMemo: PurrMemo = (name: string) => {
  if (!purrMemo.cachedName) {
    purrMemo.cachedName = name;
  }
  return purrMemo.cachedName;
}

/** overloading */

type PurrWithAttitudes = {
  (): string,
  (name: string): string,
  (name: string, times: number): string,
}
const purrWithAttitudes: PurrWithAttitudes = (name?: string, times?: number) => {
  if (!name) {
    return 'no hello';
  } else if (!times) {
    return 'hello, ' + name;
  } else {
    let count = 0, greeting = 'hello';
    while (count < times) {
      count++;
      greeting += ' hello';
    }
    return greeting + ', ' + name;
  }
}`

More Notes

Try Flow bookmarklets

Other resources

Guides

Books

  • Programming TypeScript A practical handbook on TypeScript that also explains the whys and hows behind static type checking well, see also swyx's recommendation tweet

Contributing

Questions are always welcome!

Currently, I am still in the process of organizing my notes, after setting up an initial structure I'd like to invite more people to learn and share together.

You can’t perform that action at this time.