title | layout | category | updated | weight | tags | |
---|---|---|---|---|---|---|
Flow |
2017/sheet |
JavaScript libraries |
2020-07-05 |
-3 |
|
{: .-three-column}
{: .-prime}
/* @flow */
function square (n: number) {
return n * n
}
const four = square(2)
{: data-line="1,2"}
Most of what you need to do is to simply add annotations to function arguments!
See: flow.org docs
function square (n: number) {
const result = n * n
}
{: data-line="2"}
result
is inferred to be a number because number * number
will result in a number. There's no need to give it annotations.
type Person = {
name: string,
age: number,
isAdmin: boolean,
likes: Array<string>
}
{: data-line="1,2,3,4,5,6"}
function greet(user: Person) {
console.log('hello', user.name)
}
{: data-line="1"}
greet({ name: 'Miles Davis', ··· })
This is the typical way to define the shape of complex objects.
const count: number = 200
You typically don't need to do this, function args are often enough.
See: Variable types
import type { Person } from './types'
export type Person = {
···
}
See: Module types
type Action = number | string
type Direction = 'left' | 'right'
See: Unions
type Album = {
name: ?string
}
{: data-line="2"}
const a: Album = { } // ✗ Error
const a: Album = { name: 'Blue' } // ✓ OK
const a: Album = { name: null } // ✓ OK
const a: Album = { name: undefined } // ✓ OK
This makes name
either a string or null.
See: Maybe types
type Album = {
name?: string
}
{: data-line="2"}
const a: Album = { } // ✓ OK
a.name = 'Blue' // ✓ OK
a.name = null // ✗ Error
a.name = undefined // ✓ OK
This makes an Album
valid even if name
is not part of the keys. This is different from "maybe" types.
See: Optional properties
{: .-three-column}
type Artist = {
name: string,
label: string
}
const a: Artist = {
name: 'Miguel Migs',
label: 'Naked Music',
genre: 'House' // ✓ OK
}
{: data-line="6"}
A type with more properties is "wider" and is a subtype of a "narrower" type.
See: Width subtyping
type Artist = {|
name: string,
label: string
|}
{: data-line="1,4"}
const a: Artist = {
name: 'Miguel Migs',
label: 'Naked Music',
genre: 'House' // ✗ Error
}
{: data-line="4"}
Exact object types prevent extra properties from being added to an object.
See: Exact object types
type Items = {
[key: string]: Item
}
{: data-line="2"}
See: Dynamic object keys
Type | Description |
---|---|
any |
|
boolean |
|
mixed |
|
number |
|
string |
|
void |
undefined |
null |
null (but not undefined) |
--- | --- |
{a: Number} |
Object with a shape |
[any, number] |
Tuples (fixed-length arrays) |
--- | --- |
Array<T> |
|
Class<T> |
|
Function |
|
Object |
|
--- | --- |
?number |
Maybe (number, void, null) |
`a | b` |
type Suit = "Diamonds" | "Clubs" | "Hearts" | "Spades"
const countries = {
US: "United States",
IT: "Italy",
FR: "France"
}
type Country = $Keys<typeof countries>
See: Enums
type Tree = {
foo: string,
bar: number,
qux: (foo: string, bar: number) => boolean
}
type Generic<T> = {
foo: T
}
See: Type aliases
class GenericClass<T> {
x: T
constructor (x: T) { ... }
}
var n: GenericClass<number> = new GenericClass(0)
See: Generic classes
interface Jsonable {
toJSON(): string
}
class Foo {
toJSON() { return '{}' }
}
(new Foo: Jsonable)
See: Interfaces
const callback: () => void = function () {}
function filter<T> (
list: Array<T>,
callback: (item: T) => boolean
): Array<T> {
···
}
See: Functions
import type { Person } from '../person'
import typeof Config from '../config'
export type Person = { id: string }
/*::
export type Foo = { ... }
*/
function add(n /*: number */) { ... }
type Props = {
bar: number,
}
type State = {
open: boolean,
}
class Foo extends React.Component<Props, State> {
// Component code
}
var myNumbers: Array<number> = [42]
function foo(): any { return 42 }
var b: boolean = false
var b: ?boolean = false /* maybe */
var b: string | boolean = false
var a: Class<MyClass> = MyClass
var b: MyClass = new a()
type Callback = (?Error, string) => any
function fetch (callback: Callback) {
···
}
- Flow website (flow.org)
- Getting started with Flow (flow.org)
- Flow type cheatsheet (saltycrane.com)