OSDN Git Service

Regular updates
[twpd/master.git] / flow.md
1 ---
2 title: Flow
3 layout: 2017/sheet
4 category: JavaScript libraries
5 updated: 2018-11-07
6 weight: -3
7 tags: [Featurable]
8 ---
9
10 ## Getting started
11 {: .-three-column}
12
13 ### Simple example
14 {: .-prime}
15
16 ```js
17 /* @flow */
18 function square (n: number) {
19   return n * n
20 }
21
22 const four = square(2)
23 ```
24 {: data-line="1,2"}
25
26 Most of what you need to do is to simply add annotations to function arguments!
27
28 See: [flow.org docs](https://flow.org/en/docs/)
29
30 ### Type inference
31
32 ```js
33 function square (n: number) {
34   const result = n * n
35 }
36 ```
37 {: data-line="2"}
38
39 `result` is inferred to be a number because `number * number` will result in a number. There's no need to give it annotations.
40
41 ### Type aliases
42
43 ```js
44 type Person = {
45   name: string,
46   age: number,
47   isAdmin: boolean,
48   likes: Array<string>
49 }
50 ```
51 {: data-line="1,2,3,4,5,6"}
52
53 ```js
54 function greet(user: Person) {
55   console.log('hello', user.name)
56 }
57 ```
58 {: data-line="1"}
59
60 ```js
61 greet({ name: 'Miles Davis', ··· })
62 ```
63
64 This is the typical way to define the shape of complex objects.
65
66 ### Variables
67
68 ```js
69 const count: number = 200
70 ```
71
72 You typically don't need to do this, function args are often enough.
73
74 See: [Variable types](https://flow.org/en/docs/types/variables/)
75
76 ### Importing and exporting
77
78 ```js
79 import type { Person } from './types'
80 ```
81
82 ```js
83 export type Person = {
84   ···
85 }
86 ```
87
88 See: [Module types](https://flow.org/en/docs/types/modules)
89
90 ### Union types
91
92 ```js
93 type Action = number | string
94 ```
95
96 ```js
97 type Direction = 'left' | 'right'
98 ```
99
100 See: [Unions](https://flow.org/en/docs/types/unions/)
101
102 ## Optionals
103
104 ### Maybe types
105
106 ```js
107 type Album = {
108   name: ?string
109 }
110 ```
111 {: data-line="2"}
112
113 ```js
114 const a: Album = { }                 // ✗ Error
115 const a: Album = { name: 'Blue' }    // ✓ OK
116 const a: Album = { name: null }      // ✓ OK
117 const a: Album = { name: undefined } // ✓ OK
118 ```
119
120 This makes `name` either a string or null.
121
122 See: [Maybe types](https://flow.org/en/docs/types/primitives/#toc-maybe-types)
123
124 ### Optional properties
125
126 ```js
127 type Album = {
128   name?: string
129 }
130 ```
131 {: data-line="2"}
132
133 ```js
134 const a: Album = { } // ✓ OK
135 a.name = 'Blue'      // ✓ OK
136 a.name = null        // ✗ Error
137 a.name = undefined   // ✓ OK
138 ```
139
140 This makes an `Album` valid even if `name` is not part of the keys. This is different from "maybe" types.
141
142 See: [Optional properties](https://flow.org/en/docs/types/primitives/#toc-optional-object-properties)
143
144 ## Objects
145 {: .-three-column}
146
147 ### Extra object fields
148
149 ```js
150 type Artist = {
151   name: string,
152   label: string
153 }
154 ```
155
156 ```js
157 const a: Artist = {
158   name: 'Miguel Migs',
159   label: 'Naked Music'
160 }
161
162 a.genre = 'House' // ✓ OK
163 ```
164 {: data-line="6"}
165
166 You can add more fields to an object.
167
168 See: [Width subtyping](https://flow.org/en/docs/lang/width-subtyping/)
169
170 ### Exact object types
171
172 ```js
173 type Artist = {|
174   name: string,
175   label: string
176 |}
177 ```
178 {: data-line="1,4"}
179
180 ```js
181 const a: Artist = { ··· }
182 a.genre = 'House' // ✗ Error
183 ```
184 {: data-line="2"}
185
186 Exact object types prevent extra properties from being added to an object.
187
188 See: [Exact object types](https://flow.org/en/docs/types/objects/#toc-exact-object-types)
189
190 ### Dynamic keys
191
192 ```js
193 type Items = {
194   [key: string]: Item
195 }
196 ```
197 {: data-line="2"}
198
199 See: [Dynamic object keys](https://flow.org/docs/objects.html#objects-as-maps)
200
201 ## Advanced features
202
203 ### Primitives
204
205 | Type            | Description                  |
206 | ---             | ---                          |
207 | `any`           |                              |
208 | `boolean`       |                              |
209 | `mixed`         |                              |
210 | `number`        |                              |
211 | `string`        |                              |
212 | `void`          | undefined                    |
213 | `null`          | null (but not undefined)     |
214 | ---             | ---                          |
215 | `{a: Number}`   | Object with a shape          |
216 | `[any, number]` | Tuples (fixed-length arrays) |
217 | ---             | ---                          |
218 | `Array<T>`      |                              |
219 | `Class<T>`      |                              |
220 | `Function`      |                              |
221 | `Object`        |                              |
222 | ---             | ---                          |
223 | `?number`       | Maybe (number, void, null)   |
224 | `a | b`         | Union types                  |
225
226 ### Enums
227
228 ```js
229 type Suit = "Diamonds" | "Clubs" | "Hearts" | "Spades"
230
231 const countries = {
232   US: "United States",
233   IT: "Italy",
234   FR: "France"
235 }
236
237 type Country = $Keys<typeof countries>
238 ```
239
240 See: [Enums](https://flow.org/docs/utility-types.html#keyst)
241
242 ### Type aliases
243
244 ```js
245 type Tree = {
246   foo: string,
247   bar: number,
248   qux: (foo: string, bar: number) => boolean
249 }
250
251 type Generic<T> = {
252   foo: T
253 }
254 ```
255
256 See: [Type aliases](https://flow.org/docs/quick-reference.html#type-aliases)
257
258 ### Generic classes
259
260 ```js
261 class GenericClass<T> {
262   x: T
263   constructor (x: T) { ... }
264 }
265
266 var n: GenericClass<number> = new GenericClass(0)
267 ```
268
269 See: [Generic classes](https://flow.org/docs/quick-reference.html#generics)
270
271 ### Interfaces
272
273 ```js
274 interface Jsonable {
275   toJSON(): string
276 }
277
278 class Foo {
279   toJSON() { return '{}' }
280 }
281
282 (new Foo: Jsonable)
283 ```
284
285 See: [Interfaces](https://flow.org/docs/quick-reference.html#interfaces)
286
287 ### Functions
288
289 ```js
290 const callback: () => void = function () {}
291 ```
292
293 ```js
294 function filter<T> (
295   list: Array<T>,
296   callback: (item: T) => boolean
297 ): Array<T> {
298   ···
299 }
300 ```
301
302 See: [Functions](https://flow.org/docs/functions.html)
303
304 ### Imports
305
306 ```js
307 import type { Person } from '../person'
308 import typeof Config from '../config'
309 ```
310
311 ```js
312 export type Person = { id: string }
313 ```
314
315 ### Comment syntax
316
317 ```js
318 /*::
319   export type Foo = { ... }
320 */
321
322 function add(n /*: number */) { ... }
323 ```
324
325 ### React
326
327 ```js
328 type Props = {
329   bar: number,
330 }
331
332 type State = {
333   open: boolean,
334 }
335
336 class Foo extends React.Component<Props, State> {
337   // Component code
338 }
339 ```
340
341 ## Examples
342
343 ### Examples
344
345 ```js
346 var myNumbers: Array<number> = [42]
347 function foo(): any { return 42 }
348 var b: boolean = false
349 var b: ?boolean = false  /* maybe */
350 var b: string | boolean = false
351
352 var a: Class<MyClass> = MyClass
353 var b: MyClass = new a()
354 ```
355
356 ### Function signature
357
358 ```js
359 type Callback = (?Error, string) => any
360
361 function fetch (callback: Callback) {
362   ···
363 }
364 ```
365
366 ## References
367
368 - [Flow website](https://www.saltycrane.com/flow-type-cheat-sheet/latest/) _(flow.org)_
369 - [Getting started with Flow](https://flow.org/en/docs/getting-started/) _(flow.org)_
370 - [Flow type cheatsheet](https://www.saltycrane.com/flow-type-cheat-sheet/latest/) _(saltycrane.com)_