cheatsheets/flow.md

372 lines
6.5 KiB
Markdown
Raw Permalink Normal View History

2017-08-28 19:18:32 +00:00
---
title: Flow
2017-08-28 20:47:11 +00:00
category: JavaScript libraries
2020-07-05 11:11:36 +00:00
updated: 2020-07-05
2017-09-20 08:52:04 +00:00
weight: -3
tags: [Featurable]
2017-08-28 19:18:32 +00:00
---
2017-09-20 08:52:04 +00:00
## Getting started
{: .-three-column}
### Simple example
{: .-prime}
2017-08-28 19:18:32 +00:00
```js
/* @flow */
2017-09-20 08:52:04 +00:00
function square (n: number) {
return n * n
}
2017-08-28 19:18:32 +00:00
2017-09-20 08:52:04 +00:00
const four = square(2)
2017-08-28 19:18:32 +00:00
```
2017-09-20 08:52:04 +00:00
{: data-line="1,2"}
Most of what you need to do is to simply add annotations to function arguments!
See: [flow.org docs](https://flow.org/en/docs/)
2017-08-28 19:18:32 +00:00
2017-09-21 05:10:14 +00:00
### Type inference
```js
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.
2017-09-20 08:52:04 +00:00
### Type aliases
```js
type Person = {
name: string,
age: number,
isAdmin: boolean,
likes: Array<string>
}
```
{: data-line="1,2,3,4,5,6"}
2017-08-28 19:18:32 +00:00
```js
2017-09-20 08:52:04 +00:00
function greet(user: Person) {
console.log('hello', user.name)
}
2017-08-28 19:18:32 +00:00
```
2017-09-20 08:52:04 +00:00
{: data-line="1"}
2017-08-28 19:18:32 +00:00
```js
2017-09-20 08:52:04 +00:00
greet({ name: 'Miles Davis', ··· })
2017-08-28 19:18:32 +00:00
```
2017-09-20 08:52:04 +00:00
This is the typical way to define the shape of complex objects.
### Variables
```js
const count: number = 200
```
You typically don't need to do this, function args are often enough.
See: [Variable types](https://flow.org/en/docs/types/variables/)
### Importing and exporting
```js
import type { Person } from './types'
```
```js
export type Person = {
···
}
```
See: [Module types](https://flow.org/en/docs/types/modules)
### Union types
```js
type Action = number | string
```
```js
type Direction = 'left' | 'right'
```
See: [Unions](https://flow.org/en/docs/types/unions/)
## Optionals
### Maybe types
```js
type Album = {
name: ?string
}
```
{: data-line="2"}
```js
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](https://flow.org/en/docs/types/primitives/#toc-maybe-types)
### Optional properties
```js
type Album = {
name?: string
}
```
{: data-line="2"}
```js
const a: Album = { } // ✓ OK
a.name = 'Blue' // ✓ OK
a.name = null // ✗ Error
2017-09-20 08:52:04 +00:00
a.name = undefined // ✓ OK
```
2018-04-17 15:25:06 +00:00
This makes an `Album` valid even if `name` is not part of the keys. This is different from "maybe" types.
2017-09-20 08:52:04 +00:00
See: [Optional properties](https://flow.org/en/docs/types/primitives/#toc-optional-object-properties)
## Objects
{: .-three-column}
### Width subtyping
2017-09-20 08:52:04 +00:00
```js
type Artist = {
name: string,
label: string
}
```
```js
const a: Artist = {
name: 'Miguel Migs',
label: 'Naked Music',
genre: 'House' // ✓ OK
2017-09-20 08:52:04 +00:00
}
```
{: data-line="6"}
A type with more properties is "wider" and is a subtype of a "narrower" type.
2017-09-20 08:52:04 +00:00
See: [Width subtyping](https://flow.org/en/docs/lang/width-subtyping/)
### Exact object types
```js
type Artist = {|
name: string,
label: string
|}
```
{: data-line="1,4"}
```js
const a: Artist = {
name: 'Miguel Migs',
label: 'Naked Music',
genre: 'House' // ✗ Error
}
2017-09-20 08:52:04 +00:00
```
{: data-line="4"}
2017-09-20 08:52:04 +00:00
Exact object types prevent extra properties from being added to an object.
See: [Exact object types](https://flow.org/en/docs/types/objects/#toc-exact-object-types)
### Dynamic keys
```js
type Items = {
[key: string]: Item
}
```
{: data-line="2"}
See: [Dynamic object keys](https://flow.org/en/docs/types/objects/#toc-objects-as-maps)
2017-09-20 08:52:04 +00:00
## Advanced features
2017-08-28 19:18:32 +00:00
### Primitives
| 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` | Union types |
### Enums
```js
type Suit = "Diamonds" | "Clubs" | "Hearts" | "Spades"
const countries = {
US: "United States",
IT: "Italy",
FR: "France"
}
type Country = $Keys<typeof countries>
```
See: [Enums](https://flow.org/en/docs/types/utilities/#toc-keys)
2017-08-28 19:18:32 +00:00
### Type aliases
```js
type Tree = {
foo: string,
bar: number,
qux: (foo: string, bar: number) => boolean
}
type Generic<T> = {
foo: T
}
```
See: [Type aliases](https://flow.org/en/docs/types/aliases/)
2017-08-28 19:18:32 +00:00
### Generic classes
```js
class GenericClass<T> {
x: T
constructor (x: T) { ... }
}
var n: GenericClass<number> = new GenericClass(0)
```
See: [Generic classes](https://flow.org/en/docs/types/generics/#toc-classes-with-generics)
2017-08-28 19:18:32 +00:00
### Interfaces
```js
interface Jsonable {
toJSON(): string
}
class Foo {
toJSON() { return '{}' }
}
(new Foo: Jsonable)
```
See: [Interfaces](https://flow.org/en/docs/types/interfaces/)
2017-08-28 19:18:32 +00:00
### Functions
```js
const callback: () => void = function () {}
```
```js
function filter<T> (
list: Array<T>,
callback: (item: T) => boolean
): Array<T> {
···
}
```
See: [Functions](https://flow.org/en/docs/types/functions/)
2017-08-28 19:18:32 +00:00
### Imports
```js
import type { Person } from '../person'
import typeof Config from '../config'
```
```js
export type Person = { id: string }
```
### Comment syntax
```js
/*::
export type Foo = { ... }
*/
function add(n /*: number */) { ... }
```
### React
```js
type Props = {
bar: number,
}
2017-08-28 19:18:32 +00:00
type State = {
open: boolean,
}
class Foo extends React.Component<Props, State> {
// Component code
2017-08-28 19:18:32 +00:00
}
```
2017-09-20 08:52:04 +00:00
2017-08-28 19:18:32 +00:00
## Examples
### Examples
```js
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()
```
### Function signature
```js
2017-09-20 08:52:04 +00:00
type Callback = (?Error, string) => any
2017-08-28 19:18:32 +00:00
2017-09-20 08:52:04 +00:00
function fetch (callback: Callback) {
···
2017-08-28 19:18:32 +00:00
}
```
2017-10-10 12:38:37 +00:00
## References
- [Flow website](https://www.saltycrane.com/flow-type-cheat-sheet/latest/) _(flow.org)_
- [Getting started with Flow](https://flow.org/en/docs/getting-started/) _(flow.org)_
- [Flow type cheatsheet](https://www.saltycrane.com/flow-type-cheat-sheet/latest/) _(saltycrane.com)_