OSDN Git Service

Regular updates
[twpd/master.git] / flow.md
1 ---
2 title: Flow
3 layout: 2017/sheet
4 category: JavaScript libraries
5 updated: 2020-07-05
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 ### Width subtyping
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   genre: 'House' // ✓ OK
161 }
162 ```
163 {: data-line="6"}
164
165 A type with more properties is "wider" and is a subtype of a "narrower" type.
166
167 See: [Width subtyping](https://flow.org/en/docs/lang/width-subtyping/)
168
169 ### Exact object types
170
171 ```js
172 type Artist = {|
173   name: string,
174   label: string
175 |}
176 ```
177 {: data-line="1,4"}
178
179 ```js
180 const a: Artist = {
181   name: 'Miguel Migs',
182   label: 'Naked Music',
183   genre: 'House' // ✗ Error
184 }
185 ```
186 {: data-line="4"}
187
188 Exact object types prevent extra properties from being added to an object.
189
190 See: [Exact object types](https://flow.org/en/docs/types/objects/#toc-exact-object-types)
191
192 ### Dynamic keys
193
194 ```js
195 type Items = {
196   [key: string]: Item
197 }
198 ```
199 {: data-line="2"}
200
201 See: [Dynamic object keys](https://flow.org/en/docs/types/objects/#toc-objects-as-maps)
202
203 ## Advanced features
204
205 ### Primitives
206
207 | Type            | Description                  |
208 | ---             | ---                          |
209 | `any`           |                              |
210 | `boolean`       |                              |
211 | `mixed`         |                              |
212 | `number`        |                              |
213 | `string`        |                              |
214 | `void`          | undefined                    |
215 | `null`          | null (but not undefined)     |
216 | ---             | ---                          |
217 | `{a: Number}`   | Object with a shape          |
218 | `[any, number]` | Tuples (fixed-length arrays) |
219 | ---             | ---                          |
220 | `Array<T>`      |                              |
221 | `Class<T>`      |                              |
222 | `Function`      |                              |
223 | `Object`        |                              |
224 | ---             | ---                          |
225 | `?number`       | Maybe (number, void, null)   |
226 | `a | b`         | Union types                  |
227
228 ### Enums
229
230 ```js
231 type Suit = "Diamonds" | "Clubs" | "Hearts" | "Spades"
232
233 const countries = {
234   US: "United States",
235   IT: "Italy",
236   FR: "France"
237 }
238
239 type Country = $Keys<typeof countries>
240 ```
241
242 See: [Enums](https://flow.org/en/docs/types/utilities/#toc-keys)
243
244 ### Type aliases
245
246 ```js
247 type Tree = {
248   foo: string,
249   bar: number,
250   qux: (foo: string, bar: number) => boolean
251 }
252
253 type Generic<T> = {
254   foo: T
255 }
256 ```
257
258 See: [Type aliases](https://flow.org/en/docs/types/aliases/)
259
260 ### Generic classes
261
262 ```js
263 class GenericClass<T> {
264   x: T
265   constructor (x: T) { ... }
266 }
267
268 var n: GenericClass<number> = new GenericClass(0)
269 ```
270
271 See: [Generic classes](https://flow.org/en/docs/types/generics/#toc-classes-with-generics)
272
273 ### Interfaces
274
275 ```js
276 interface Jsonable {
277   toJSON(): string
278 }
279
280 class Foo {
281   toJSON() { return '{}' }
282 }
283
284 (new Foo: Jsonable)
285 ```
286
287 See: [Interfaces](https://flow.org/en/docs/types/interfaces/)
288
289 ### Functions
290
291 ```js
292 const callback: () => void = function () {}
293 ```
294
295 ```js
296 function filter<T> (
297   list: Array<T>,
298   callback: (item: T) => boolean
299 ): Array<T> {
300   ···
301 }
302 ```
303
304 See: [Functions](https://flow.org/en/docs/types/functions/)
305
306 ### Imports
307
308 ```js
309 import type { Person } from '../person'
310 import typeof Config from '../config'
311 ```
312
313 ```js
314 export type Person = { id: string }
315 ```
316
317 ### Comment syntax
318
319 ```js
320 /*::
321   export type Foo = { ... }
322 */
323
324 function add(n /*: number */) { ... }
325 ```
326
327 ### React
328
329 ```js
330 type Props = {
331   bar: number,
332 }
333
334 type State = {
335   open: boolean,
336 }
337
338 class Foo extends React.Component<Props, State> {
339   // Component code
340 }
341 ```
342
343 ## Examples
344
345 ### Examples
346
347 ```js
348 var myNumbers: Array<number> = [42]
349 function foo(): any { return 42 }
350 var b: boolean = false
351 var b: ?boolean = false  /* maybe */
352 var b: string | boolean = false
353
354 var a: Class<MyClass> = MyClass
355 var b: MyClass = new a()
356 ```
357
358 ### Function signature
359
360 ```js
361 type Callback = (?Error, string) => any
362
363 function fetch (callback: Callback) {
364   ···
365 }
366 ```
367
368 ## References
369
370 - [Flow website](https://www.saltycrane.com/flow-type-cheat-sheet/latest/) _(flow.org)_
371 - [Getting started with Flow](https://flow.org/en/docs/getting-started/) _(flow.org)_
372 - [Flow type cheatsheet](https://www.saltycrane.com/flow-type-cheat-sheet/latest/) _(saltycrane.com)_