Redux has three major parts that should be typed:
Typing Redux state
Typing your state
object, works the same as typing any other object in Flow.
1
2
3
4
5
6
7
8
9
10
|
type State = {
users: Array<{
id: string
name: string,
age: number,
phoneNumber: string,
}>,
activeUserID: string,
};
|
{"value":"type State = {\n users: Array<{\n id: string\n name: string,\n age: number,\n phoneNumber: string,\n }>,\n activeUserID: string,\n // ...\n};\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"State","line":1,"start":5,"end":10},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":11,"end":12},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":13,"end":14},{"type":"T_IDENTIFIER","context":"normal","value":"users","line":2,"start":17,"end":22},{"type":"T_COLON","context":"type","value":":","line":2,"start":22,"end":23},{"type":"T_IDENTIFIER","context":"type","value":"Array","line":2,"start":24,"end":29},{"type":"T_LESS_THAN","context":"type","value":"<","line":2,"start":29,"end":30},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":30,"end":31},{"type":"T_IDENTIFIER","context":"normal","value":"id","line":3,"start":36,"end":38},{"type":"T_COLON","context":"type","value":":","line":3,"start":38,"end":39},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":40,"end":46},{"type":"T_IDENTIFIER","context":"normal","value":"name","line":4,"start":51,"end":55},{"type":"T_COLON","context":"type","value":":","line":4,"start":55,"end":56},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":57,"end":63},{"type":"T_COMMA","context":"type","value":",","line":4,"start":63,"end":64},{"type":"T_IDENTIFIER","context":"normal","value":"age","line":5,"start":69,"end":72},{"type":"T_COLON","context":"type","value":":","line":5,"start":72,"end":73},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":5,"start":74,"end":80},{"type":"T_COMMA","context":"type","value":",","line":5,"start":80,"end":81},{"type":"T_IDENTIFIER","context":"normal","value":"phoneNumber","line":6,"start":86,"end":97},{"type":"T_COLON","context":"type","value":":","line":6,"start":97,"end":98},{"type":"T_STRING_TYPE","context":"type","value":"string","line":6,"start":99,"end":105},{"type":"T_COMMA","context":"type","value":",","line":6,"start":105,"end":106},{"type":"T_RCURLY","context":"type","value":"}","line":7,"start":109,"end":110},{"type":"T_GREATER_THAN","context":"type","value":">","line":7,"start":110,"end":111},{"type":"T_COMMA","context":"type","value":",","line":7,"start":111,"end":112},{"type":"T_IDENTIFIER","context":"normal","value":"activeUserID","line":8,"start":115,"end":127},{"type":"T_COLON","context":"type","value":":","line":8,"start":127,"end":128},{"type":"T_STRING_TYPE","context":"type","value":"string","line":8,"start":129,"end":135},{"type":"T_COMMA","context":"type","value":",","line":8,"start":135,"end":136},{"type":"Line","context":"comment","value":"// ...","line":9,"start":139,"end":145},{"type":"T_RCURLY","context":"type","value":"}","line":10,"start":146,"end":147},{"type":"T_SEMICOLON","context":"type","value":";","line":10,"start":147,"end":148}],"errors":[]}
We can use this type alias to make sure reducers work correctly.
Typing Redux state immutability
Redux state is meant to be immutable:
creating a new state object instead of changing properties on a single object.
You can enforce this in Flow by making every property effectively “read-only”
using “covariant” properties throughout your state object.
1
2
3
4
5
6
7
8
9
10
|
type State = {
+users: Array<{
+id: string
+name: string,
+age: number,
+phoneNumber: string,
}>,
+activeUserID: string,
};
|
{"value":"type State = {\n +users: Array<{\n +id: string\n +name: string,\n +age: number,\n +phoneNumber: string,\n }>,\n +activeUserID: string,\n // ...\n};\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"State","line":1,"start":5,"end":10},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":11,"end":12},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":13,"end":14},{"type":"T_PLUS","context":"type","value":"+","line":2,"start":17,"end":18},{"type":"T_IDENTIFIER","context":"normal","value":"users","line":2,"start":18,"end":23},{"type":"T_COLON","context":"type","value":":","line":2,"start":23,"end":24},{"type":"T_IDENTIFIER","context":"type","value":"Array","line":2,"start":25,"end":30},{"type":"T_LESS_THAN","context":"type","value":"<","line":2,"start":30,"end":31},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":31,"end":32},{"type":"T_PLUS","context":"type","value":"+","line":3,"start":37,"end":38},{"type":"T_IDENTIFIER","context":"normal","value":"id","line":3,"start":38,"end":40},{"type":"T_COLON","context":"type","value":":","line":3,"start":40,"end":41},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":42,"end":48},{"type":"T_PLUS","context":"type","value":"+","line":4,"start":53,"end":54},{"type":"T_IDENTIFIER","context":"normal","value":"name","line":4,"start":54,"end":58},{"type":"T_COLON","context":"type","value":":","line":4,"start":58,"end":59},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":60,"end":66},{"type":"T_COMMA","context":"type","value":",","line":4,"start":66,"end":67},{"type":"T_PLUS","context":"type","value":"+","line":5,"start":72,"end":73},{"type":"T_IDENTIFIER","context":"normal","value":"age","line":5,"start":73,"end":76},{"type":"T_COLON","context":"type","value":":","line":5,"start":76,"end":77},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":5,"start":78,"end":84},{"type":"T_COMMA","context":"type","value":",","line":5,"start":84,"end":85},{"type":"T_PLUS","context":"type","value":"+","line":6,"start":90,"end":91},{"type":"T_IDENTIFIER","context":"normal","value":"phoneNumber","line":6,"start":91,"end":102},{"type":"T_COLON","context":"type","value":":","line":6,"start":102,"end":103},{"type":"T_STRING_TYPE","context":"type","value":"string","line":6,"start":104,"end":110},{"type":"T_COMMA","context":"type","value":",","line":6,"start":110,"end":111},{"type":"T_RCURLY","context":"type","value":"}","line":7,"start":114,"end":115},{"type":"T_GREATER_THAN","context":"type","value":">","line":7,"start":115,"end":116},{"type":"T_COMMA","context":"type","value":",","line":7,"start":116,"end":117},{"type":"T_PLUS","context":"type","value":"+","line":8,"start":120,"end":121},{"type":"T_IDENTIFIER","context":"normal","value":"activeUserID","line":8,"start":121,"end":133},{"type":"T_COLON","context":"type","value":":","line":8,"start":133,"end":134},{"type":"T_STRING_TYPE","context":"type","value":"string","line":8,"start":135,"end":141},{"type":"T_COMMA","context":"type","value":",","line":8,"start":141,"end":142},{"type":"Line","context":"comment","value":"// ...","line":9,"start":145,"end":151},{"type":"T_RCURLY","context":"type","value":"}","line":10,"start":152,"end":153},{"type":"T_SEMICOLON","context":"type","value":";","line":10,"start":153,"end":154}],"errors":[]}
Now Flow will complain when you try to write to any of these properties.
1
2
3
4
5
6
7
8
9
10
|
type State = {
+foo: string
};
let state: State = {
foo: "foo"
};
state.foo = "bar";
|
object type Covariant property `foo` incompatible with contravariant use in assignment of property `foo`
{"value":"// @flow\ntype State = {\n +foo: string\n};\n\nlet state: State = {\n foo: \"foo\"\n};\n\nstate.foo = \"bar\"; // Error!\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"State","line":2,"start":14,"end":19},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":20,"end":21},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":22,"end":23},{"type":"T_PLUS","context":"type","value":"+","line":3,"start":26,"end":27},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":3,"start":27,"end":30},{"type":"T_COLON","context":"type","value":":","line":3,"start":30,"end":31},{"type":"T_STRING_TYPE","context":"type","value":"string","line":3,"start":32,"end":38},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":39,"end":40},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":40,"end":41},{"type":"T_LET","context":"normal","value":"let","line":6,"start":43,"end":46},{"type":"T_IDENTIFIER","context":"normal","value":"state","line":6,"start":47,"end":52},{"type":"T_COLON","context":"type","value":":","line":6,"start":52,"end":53},{"type":"T_IDENTIFIER","context":"type","value":"State","line":6,"start":54,"end":59},{"type":"T_ASSIGN","context":"normal","value":"=","line":6,"start":60,"end":61},{"type":"T_LCURLY","context":"normal","value":"{","line":6,"start":62,"end":63},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":7,"start":66,"end":69},{"type":"T_COLON","context":"normal","value":":","line":7,"start":69,"end":70},{"type":"T_STRING","context":"normal","value":"\"foo\"","line":7,"start":71,"end":76},{"type":"T_RCURLY","context":"normal","value":"}","line":8,"start":77,"end":78},{"type":"T_SEMICOLON","context":"normal","value":";","line":8,"start":78,"end":79},{"type":"T_IDENTIFIER","context":"normal","value":"state","line":10,"start":81,"end":86},{"type":"T_PERIOD","context":"normal","value":".","line":10,"start":86,"end":87},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":10,"start":87,"end":90},{"type":"T_ASSIGN","context":"normal","value":"=","line":10,"start":91,"end":92},{"type":"T_STRING","context":"normal","value":"\"bar\"","line":10,"start":93,"end":98},{"type":"T_SEMICOLON","context":"normal","value":";","line":10,"start":98,"end":99},{"type":"Line","context":"comment","value":"// Error!","line":10,"start":100,"end":109}],"errors":[{"id":"E1","messages":[{"id":"E1M1","description":"object type","context":"state.foo = \"bar\"; // Error!","source":"-","start":{"line":10,"column":1,"offset":81},"end":{"line":10,"column":5,"offset":86}},{"id":"E1M2","description":"Covariant property `foo` incompatible with contravariant use in","context":null,"source":null,"start":null,"end":null},{"id":"E1M3","description":"assignment of property `foo`","context":"state.foo = \"bar\"; // Error!","source":"-","start":{"line":10,"column":1,"offset":81},"end":{"line":10,"column":9,"offset":90}}],"operation":null}]}
Typing Redux actions
The base type for Redux actions
is an object with a type
property.
1
2
3
|
type Action = {
+type: string,
};
|
{"value":"type Action = {\n +type: string,\n};\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":1,"start":5,"end":11},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":12,"end":13},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":14,"end":15},{"type":"T_PLUS","context":"type","value":"+","line":2,"start":18,"end":19},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":19,"end":23},{"type":"T_COLON","context":"type","value":":","line":2,"start":23,"end":24},{"type":"T_STRING_TYPE","context":"type","value":"string","line":2,"start":25,"end":31},{"type":"T_COMMA","context":"type","value":",","line":2,"start":31,"end":32},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":33,"end":34},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":34,"end":35}],"errors":[]}
But you’ll want to use more specific types for your actions using disjoint
unions and each individual type of action.
1
2
3
4
|
type Action =
| { type: "FOO", foo: number }
| { type: "BAR", bar: boolean }
| { type: "BAZ", baz: string };
|
{"value":"type Action =\n | { type: \"FOO\", foo: number }\n | { type: \"BAR\", bar: boolean }\n | { type: \"BAZ\", baz: string };\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":1,"start":5,"end":11},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":12,"end":13},{"type":"T_BIT_OR","context":"type","value":"|","line":2,"start":16,"end":17},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":18,"end":19},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":20,"end":24},{"type":"T_COLON","context":"type","value":":","line":2,"start":24,"end":25},{"type":"T_STRING","context":"type","value":"\"FOO\"","line":2,"start":26,"end":31},{"type":"T_COMMA","context":"type","value":",","line":2,"start":31,"end":32},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":2,"start":33,"end":36},{"type":"T_COLON","context":"type","value":":","line":2,"start":36,"end":37},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":38,"end":44},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":45,"end":46},{"type":"T_BIT_OR","context":"type","value":"|","line":3,"start":49,"end":50},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":51,"end":52},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":53,"end":57},{"type":"T_COLON","context":"type","value":":","line":3,"start":57,"end":58},{"type":"T_STRING","context":"type","value":"\"BAR\"","line":3,"start":59,"end":64},{"type":"T_COMMA","context":"type","value":",","line":3,"start":64,"end":65},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":3,"start":66,"end":69},{"type":"T_COLON","context":"type","value":":","line":3,"start":69,"end":70},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":3,"start":71,"end":78},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":79,"end":80},{"type":"T_BIT_OR","context":"type","value":"|","line":4,"start":83,"end":84},{"type":"T_LCURLY","context":"type","value":"{","line":4,"start":85,"end":86},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":87,"end":91},{"type":"T_COLON","context":"type","value":":","line":4,"start":91,"end":92},{"type":"T_STRING","context":"type","value":"\"BAZ\"","line":4,"start":93,"end":98},{"type":"T_COMMA","context":"type","value":",","line":4,"start":98,"end":99},{"type":"T_IDENTIFIER","context":"normal","value":"baz","line":4,"start":100,"end":103},{"type":"T_COLON","context":"type","value":":","line":4,"start":103,"end":104},{"type":"T_STRING_TYPE","context":"type","value":"string","line":4,"start":105,"end":111},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":112,"end":113},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":113,"end":114}],"errors":[]}
Using disjoint unions, Flow will be able to understand your reducers much
better.
Typing Redux action creators
In order to type your Redux action creators,
you’ll want to split up your Action
disjoint union into separate action
types.
1
2
3
4
5
6
|
type FooAction = { type: "FOO", foo: number };
type BarAction = { type: "BAR", bar: boolean };
type Action =
| FooAction
| BarAction;
|
{"value":"type FooAction = { type: \"FOO\", foo: number };\ntype BarAction = { type: \"BAR\", bar: boolean };\n\ntype Action =\n | FooAction\n | BarAction;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"FooAction","line":1,"start":5,"end":14},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":15,"end":16},{"type":"T_LCURLY","context":"type","value":"{","line":1,"start":17,"end":18},{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":19,"end":23},{"type":"T_COLON","context":"type","value":":","line":1,"start":23,"end":24},{"type":"T_STRING","context":"type","value":"\"FOO\"","line":1,"start":25,"end":30},{"type":"T_COMMA","context":"type","value":",","line":1,"start":30,"end":31},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":1,"start":32,"end":35},{"type":"T_COLON","context":"type","value":":","line":1,"start":35,"end":36},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":1,"start":37,"end":43},{"type":"T_RCURLY","context":"type","value":"}","line":1,"start":44,"end":45},{"type":"T_SEMICOLON","context":"type","value":";","line":1,"start":45,"end":46},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":47,"end":51},{"type":"T_IDENTIFIER","context":"type","value":"BarAction","line":2,"start":52,"end":61},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":62,"end":63},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":64,"end":65},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":66,"end":70},{"type":"T_COLON","context":"type","value":":","line":2,"start":70,"end":71},{"type":"T_STRING","context":"type","value":"\"BAR\"","line":2,"start":72,"end":77},{"type":"T_COMMA","context":"type","value":",","line":2,"start":77,"end":78},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":2,"start":79,"end":82},{"type":"T_COLON","context":"type","value":":","line":2,"start":82,"end":83},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":2,"start":84,"end":91},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":92,"end":93},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":93,"end":94},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":96,"end":100},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":4,"start":101,"end":107},{"type":"T_ASSIGN","context":"type","value":"=","line":4,"start":108,"end":109},{"type":"T_BIT_OR","context":"type","value":"|","line":5,"start":112,"end":113},{"type":"T_IDENTIFIER","context":"type","value":"FooAction","line":5,"start":114,"end":123},{"type":"T_BIT_OR","context":"type","value":"|","line":6,"start":126,"end":127},{"type":"T_IDENTIFIER","context":"type","value":"BarAction","line":6,"start":128,"end":137},{"type":"T_SEMICOLON","context":"type","value":";","line":6,"start":137,"end":138}],"errors":[]}
Then to type the action creator, just add a return type of the appropriate
action.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
type FooAction = { type: "FOO", foo: number };
type BarAction = { type: "BAR", bar: boolean };
type Action =
| FooAction
| BarAction;
function foo(value: number): FooAction {
return { type: "FOO", foo: value };
}
function bar(value: boolean): BarAction {
return { type: "BAR", bar: value };
}
|
{"value":"// @flow\ntype FooAction = { type: \"FOO\", foo: number };\ntype BarAction = { type: \"BAR\", bar: boolean };\n\ntype Action =\n | FooAction\n | BarAction;\n\nfunction foo(value: number): FooAction {\n return { type: \"FOO\", foo: value };\n}\n\nfunction bar(value: boolean): BarAction {\n return { type: \"BAR\", bar: value };\n}\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"FooAction","line":2,"start":14,"end":23},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":24,"end":25},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":26,"end":27},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":28,"end":32},{"type":"T_COLON","context":"type","value":":","line":2,"start":32,"end":33},{"type":"T_STRING","context":"type","value":"\"FOO\"","line":2,"start":34,"end":39},{"type":"T_COMMA","context":"type","value":",","line":2,"start":39,"end":40},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":2,"start":41,"end":44},{"type":"T_COLON","context":"type","value":":","line":2,"start":44,"end":45},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":46,"end":52},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":53,"end":54},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":54,"end":55},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":56,"end":60},{"type":"T_IDENTIFIER","context":"type","value":"BarAction","line":3,"start":61,"end":70},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":71,"end":72},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":73,"end":74},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":75,"end":79},{"type":"T_COLON","context":"type","value":":","line":3,"start":79,"end":80},{"type":"T_STRING","context":"type","value":"\"BAR\"","line":3,"start":81,"end":86},{"type":"T_COMMA","context":"type","value":",","line":3,"start":86,"end":87},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":3,"start":88,"end":91},{"type":"T_COLON","context":"type","value":":","line":3,"start":91,"end":92},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":3,"start":93,"end":100},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":101,"end":102},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":102,"end":103},{"type":"T_TYPE","context":"normal","value":"type","line":5,"start":105,"end":109},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":5,"start":110,"end":116},{"type":"T_ASSIGN","context":"type","value":"=","line":5,"start":117,"end":118},{"type":"T_BIT_OR","context":"type","value":"|","line":6,"start":121,"end":122},{"type":"T_IDENTIFIER","context":"type","value":"FooAction","line":6,"start":123,"end":132},{"type":"T_BIT_OR","context":"type","value":"|","line":7,"start":135,"end":136},{"type":"T_IDENTIFIER","context":"type","value":"BarAction","line":7,"start":137,"end":146},{"type":"T_SEMICOLON","context":"type","value":";","line":7,"start":146,"end":147},{"type":"T_FUNCTION","context":"normal","value":"function","line":9,"start":149,"end":157},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":9,"start":158,"end":161},{"type":"T_LPAREN","context":"normal","value":"(","line":9,"start":161,"end":162},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":9,"start":162,"end":167},{"type":"T_COLON","context":"type","value":":","line":9,"start":167,"end":168},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":9,"start":169,"end":175},{"type":"T_RPAREN","context":"normal","value":")","line":9,"start":175,"end":176},{"type":"T_COLON","context":"type","value":":","line":9,"start":176,"end":177},{"type":"T_IDENTIFIER","context":"type","value":"FooAction","line":9,"start":178,"end":187},{"type":"T_LCURLY","context":"normal","value":"{","line":9,"start":188,"end":189},{"type":"T_RETURN","context":"normal","value":"return","line":10,"start":192,"end":198},{"type":"T_LCURLY","context":"normal","value":"{","line":10,"start":199,"end":200},{"type":"T_TYPE","context":"normal","value":"type","line":10,"start":201,"end":205},{"type":"T_COLON","context":"normal","value":":","line":10,"start":205,"end":206},{"type":"T_STRING","context":"normal","value":"\"FOO\"","line":10,"start":207,"end":212},{"type":"T_COMMA","context":"normal","value":",","line":10,"start":212,"end":213},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":10,"start":214,"end":217},{"type":"T_COLON","context":"normal","value":":","line":10,"start":217,"end":218},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":10,"start":219,"end":224},{"type":"T_RCURLY","context":"normal","value":"}","line":10,"start":225,"end":226},{"type":"T_SEMICOLON","context":"normal","value":";","line":10,"start":226,"end":227},{"type":"T_RCURLY","context":"normal","value":"}","line":11,"start":228,"end":229},{"type":"T_FUNCTION","context":"normal","value":"function","line":13,"start":231,"end":239},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":13,"start":240,"end":243},{"type":"T_LPAREN","context":"normal","value":"(","line":13,"start":243,"end":244},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":13,"start":244,"end":249},{"type":"T_COLON","context":"type","value":":","line":13,"start":249,"end":250},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":13,"start":251,"end":258},{"type":"T_RPAREN","context":"normal","value":")","line":13,"start":258,"end":259},{"type":"T_COLON","context":"type","value":":","line":13,"start":259,"end":260},{"type":"T_IDENTIFIER","context":"type","value":"BarAction","line":13,"start":261,"end":270},{"type":"T_LCURLY","context":"normal","value":"{","line":13,"start":271,"end":272},{"type":"T_RETURN","context":"normal","value":"return","line":14,"start":275,"end":281},{"type":"T_LCURLY","context":"normal","value":"{","line":14,"start":282,"end":283},{"type":"T_TYPE","context":"normal","value":"type","line":14,"start":284,"end":288},{"type":"T_COLON","context":"normal","value":":","line":14,"start":288,"end":289},{"type":"T_STRING","context":"normal","value":"\"BAR\"","line":14,"start":290,"end":295},{"type":"T_COMMA","context":"normal","value":",","line":14,"start":295,"end":296},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":14,"start":297,"end":300},{"type":"T_COLON","context":"normal","value":":","line":14,"start":300,"end":301},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":14,"start":302,"end":307},{"type":"T_RCURLY","context":"normal","value":"}","line":14,"start":308,"end":309},{"type":"T_SEMICOLON","context":"normal","value":";","line":14,"start":309,"end":310},{"type":"T_RCURLY","context":"normal","value":"}","line":15,"start":311,"end":312}],"errors":[]}
Typing Redux thunk actions
In order to type your Redux thunk actions,
you’ll add types for ThunkAction
as a function Dispatch
, and GetState
. GetState
is a function that returns an Object
. Dispatch
accepts a disjoint union of Action
, ThunkAction
, PromiseAction
and Array<Action>
and can return any
.
1
2
3
4
|
type Dispatch = (action: Action | ThunkAction | PromiseAction) => any;
type GetState = () => Object;
type ThunkAction = (dispatch: Dispatch, getState: GetState) => any;
type PromiseAction = Promise<Action>;
|
{"value":"type Dispatch = (action: Action | ThunkAction | PromiseAction) => any;\ntype GetState = () => Object;\ntype ThunkAction = (dispatch: Dispatch, getState: GetState) => any;\ntype PromiseAction = Promise<Action>;\n","tokens":[{"type":"T_TYPE","context":"normal","value":"type","line":1,"start":0,"end":4},{"type":"T_IDENTIFIER","context":"type","value":"Dispatch","line":1,"start":5,"end":13},{"type":"T_ASSIGN","context":"type","value":"=","line":1,"start":14,"end":15},{"type":"T_LPAREN","context":"type","value":"(","line":1,"start":16,"end":17},{"type":"T_IDENTIFIER","context":"type","value":"action","line":1,"start":17,"end":23},{"type":"T_COLON","context":"type","value":":","line":1,"start":23,"end":24},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":1,"start":25,"end":31},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":32,"end":33},{"type":"T_IDENTIFIER","context":"type","value":"ThunkAction","line":1,"start":34,"end":45},{"type":"T_BIT_OR","context":"type","value":"|","line":1,"start":46,"end":47},{"type":"T_IDENTIFIER","context":"type","value":"PromiseAction","line":1,"start":48,"end":61},{"type":"T_RPAREN","context":"type","value":")","line":1,"start":61,"end":62},{"type":"T_ARROW","context":"type","value":"=>","line":1,"start":63,"end":65},{"type":"T_ANY_TYPE","context":"type","value":"any","line":1,"start":66,"end":69},{"type":"T_SEMICOLON","context":"type","value":";","line":1,"start":69,"end":70},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":71,"end":75},{"type":"T_IDENTIFIER","context":"type","value":"GetState","line":2,"start":76,"end":84},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":85,"end":86},{"type":"T_LPAREN","context":"type","value":"(","line":2,"start":87,"end":88},{"type":"T_RPAREN","context":"type","value":")","line":2,"start":88,"end":89},{"type":"T_ARROW","context":"type","value":"=>","line":2,"start":90,"end":92},{"type":"T_IDENTIFIER","context":"type","value":"Object","line":2,"start":93,"end":99},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":99,"end":100},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":101,"end":105},{"type":"T_IDENTIFIER","context":"type","value":"ThunkAction","line":3,"start":106,"end":117},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":118,"end":119},{"type":"T_LPAREN","context":"type","value":"(","line":3,"start":120,"end":121},{"type":"T_IDENTIFIER","context":"type","value":"dispatch","line":3,"start":121,"end":129},{"type":"T_COLON","context":"type","value":":","line":3,"start":129,"end":130},{"type":"T_IDENTIFIER","context":"type","value":"Dispatch","line":3,"start":131,"end":139},{"type":"T_COMMA","context":"type","value":",","line":3,"start":139,"end":140},{"type":"T_IDENTIFIER","context":"type","value":"getState","line":3,"start":141,"end":149},{"type":"T_COLON","context":"type","value":":","line":3,"start":149,"end":150},{"type":"T_IDENTIFIER","context":"type","value":"GetState","line":3,"start":151,"end":159},{"type":"T_RPAREN","context":"type","value":")","line":3,"start":159,"end":160},{"type":"T_ARROW","context":"type","value":"=>","line":3,"start":161,"end":163},{"type":"T_ANY_TYPE","context":"type","value":"any","line":3,"start":164,"end":167},{"type":"T_SEMICOLON","context":"type","value":";","line":3,"start":167,"end":168},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":169,"end":173},{"type":"T_IDENTIFIER","context":"type","value":"PromiseAction","line":4,"start":174,"end":187},{"type":"T_ASSIGN","context":"type","value":"=","line":4,"start":188,"end":189},{"type":"T_IDENTIFIER","context":"type","value":"Promise","line":4,"start":190,"end":197},{"type":"T_LESS_THAN","context":"type","value":"<","line":4,"start":197,"end":198},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":4,"start":198,"end":204},{"type":"T_GREATER_THAN","context":"type","value":">","line":4,"start":204,"end":205},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":205,"end":206}],"errors":[]}
Then to type a thunk action creator, add a return type of a ThunkAction
to your action creator.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
type Action =
| { type: "FOO", foo: number }
| { type: "BAR", bar: boolean };
type GetState = () => Object;
type PromiseAction = Promise<Action>;
type ThunkAction = (dispatch: Dispatch, getState: GetState) => any;
type Dispatch = (action: Action | ThunkAction | PromiseAction | Array<Action>) => any;
function foo(): ThunkAction {
return (dispatch, getState) => {
const baz = getState().baz
dispatch({ type: "BAR", bar: true })
doSomethingAsync(baz)
.then(value => {
dispatch({ type: "FOO", foo: value })
})
}
}
|
identifier `doSomethingAsync` Could not resolve name
{"value":"// @flow\ntype Action =\n | { type: \"FOO\", foo: number }\n | { type: \"BAR\", bar: boolean };\n\ntype GetState = () => Object;\ntype PromiseAction = Promise<Action>;\ntype ThunkAction = (dispatch: Dispatch, getState: GetState) => any;\ntype Dispatch = (action: Action | ThunkAction | PromiseAction | Array<Action>) => any;\n\n\nfunction foo(): ThunkAction {\n return (dispatch, getState) => {\n const baz = getState().baz\n dispatch({ type: \"BAR\", bar: true })\n doSomethingAsync(baz)\n .then(value => {\n \t dispatch({ type: \"FOO\", foo: value })\n })\n\t}\n}\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":2,"start":14,"end":20},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":21,"end":22},{"type":"T_BIT_OR","context":"type","value":"|","line":3,"start":25,"end":26},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":27,"end":28},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":29,"end":33},{"type":"T_COLON","context":"type","value":":","line":3,"start":33,"end":34},{"type":"T_STRING","context":"type","value":"\"FOO\"","line":3,"start":35,"end":40},{"type":"T_COMMA","context":"type","value":",","line":3,"start":40,"end":41},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":3,"start":42,"end":45},{"type":"T_COLON","context":"type","value":":","line":3,"start":45,"end":46},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":3,"start":47,"end":53},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":54,"end":55},{"type":"T_BIT_OR","context":"type","value":"|","line":4,"start":58,"end":59},{"type":"T_LCURLY","context":"type","value":"{","line":4,"start":60,"end":61},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":62,"end":66},{"type":"T_COLON","context":"type","value":":","line":4,"start":66,"end":67},{"type":"T_STRING","context":"type","value":"\"BAR\"","line":4,"start":68,"end":73},{"type":"T_COMMA","context":"type","value":",","line":4,"start":73,"end":74},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":4,"start":75,"end":78},{"type":"T_COLON","context":"type","value":":","line":4,"start":78,"end":79},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":4,"start":80,"end":87},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":88,"end":89},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":89,"end":90},{"type":"T_TYPE","context":"normal","value":"type","line":6,"start":92,"end":96},{"type":"T_IDENTIFIER","context":"type","value":"GetState","line":6,"start":97,"end":105},{"type":"T_ASSIGN","context":"type","value":"=","line":6,"start":106,"end":107},{"type":"T_LPAREN","context":"type","value":"(","line":6,"start":108,"end":109},{"type":"T_RPAREN","context":"type","value":")","line":6,"start":109,"end":110},{"type":"T_ARROW","context":"type","value":"=>","line":6,"start":111,"end":113},{"type":"T_IDENTIFIER","context":"type","value":"Object","line":6,"start":114,"end":120},{"type":"T_SEMICOLON","context":"type","value":";","line":6,"start":120,"end":121},{"type":"T_TYPE","context":"normal","value":"type","line":7,"start":122,"end":126},{"type":"T_IDENTIFIER","context":"type","value":"PromiseAction","line":7,"start":127,"end":140},{"type":"T_ASSIGN","context":"type","value":"=","line":7,"start":141,"end":142},{"type":"T_IDENTIFIER","context":"type","value":"Promise","line":7,"start":143,"end":150},{"type":"T_LESS_THAN","context":"type","value":"<","line":7,"start":150,"end":151},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":7,"start":151,"end":157},{"type":"T_GREATER_THAN","context":"type","value":">","line":7,"start":157,"end":158},{"type":"T_SEMICOLON","context":"type","value":";","line":7,"start":158,"end":159},{"type":"T_TYPE","context":"normal","value":"type","line":8,"start":160,"end":164},{"type":"T_IDENTIFIER","context":"type","value":"ThunkAction","line":8,"start":165,"end":176},{"type":"T_ASSIGN","context":"type","value":"=","line":8,"start":177,"end":178},{"type":"T_LPAREN","context":"type","value":"(","line":8,"start":179,"end":180},{"type":"T_IDENTIFIER","context":"type","value":"dispatch","line":8,"start":180,"end":188},{"type":"T_COLON","context":"type","value":":","line":8,"start":188,"end":189},{"type":"T_IDENTIFIER","context":"type","value":"Dispatch","line":8,"start":190,"end":198},{"type":"T_COMMA","context":"type","value":",","line":8,"start":198,"end":199},{"type":"T_IDENTIFIER","context":"type","value":"getState","line":8,"start":200,"end":208},{"type":"T_COLON","context":"type","value":":","line":8,"start":208,"end":209},{"type":"T_IDENTIFIER","context":"type","value":"GetState","line":8,"start":210,"end":218},{"type":"T_RPAREN","context":"type","value":")","line":8,"start":218,"end":219},{"type":"T_ARROW","context":"type","value":"=>","line":8,"start":220,"end":222},{"type":"T_ANY_TYPE","context":"type","value":"any","line":8,"start":223,"end":226},{"type":"T_SEMICOLON","context":"type","value":";","line":8,"start":226,"end":227},{"type":"T_TYPE","context":"normal","value":"type","line":9,"start":228,"end":232},{"type":"T_IDENTIFIER","context":"type","value":"Dispatch","line":9,"start":233,"end":241},{"type":"T_ASSIGN","context":"type","value":"=","line":9,"start":242,"end":243},{"type":"T_LPAREN","context":"type","value":"(","line":9,"start":244,"end":245},{"type":"T_IDENTIFIER","context":"type","value":"action","line":9,"start":245,"end":251},{"type":"T_COLON","context":"type","value":":","line":9,"start":251,"end":252},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":9,"start":253,"end":259},{"type":"T_BIT_OR","context":"type","value":"|","line":9,"start":260,"end":261},{"type":"T_IDENTIFIER","context":"type","value":"ThunkAction","line":9,"start":262,"end":273},{"type":"T_BIT_OR","context":"type","value":"|","line":9,"start":274,"end":275},{"type":"T_IDENTIFIER","context":"type","value":"PromiseAction","line":9,"start":276,"end":289},{"type":"T_BIT_OR","context":"type","value":"|","line":9,"start":290,"end":291},{"type":"T_IDENTIFIER","context":"type","value":"Array","line":9,"start":292,"end":297},{"type":"T_LESS_THAN","context":"type","value":"<","line":9,"start":297,"end":298},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":9,"start":298,"end":304},{"type":"T_GREATER_THAN","context":"type","value":">","line":9,"start":304,"end":305},{"type":"T_RPAREN","context":"type","value":")","line":9,"start":305,"end":306},{"type":"T_ARROW","context":"type","value":"=>","line":9,"start":307,"end":309},{"type":"T_ANY_TYPE","context":"type","value":"any","line":9,"start":310,"end":313},{"type":"T_SEMICOLON","context":"type","value":";","line":9,"start":313,"end":314},{"type":"T_FUNCTION","context":"normal","value":"function","line":12,"start":317,"end":325},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":12,"start":326,"end":329},{"type":"T_LPAREN","context":"normal","value":"(","line":12,"start":329,"end":330},{"type":"T_RPAREN","context":"normal","value":")","line":12,"start":330,"end":331},{"type":"T_COLON","context":"type","value":":","line":12,"start":331,"end":332},{"type":"T_IDENTIFIER","context":"type","value":"ThunkAction","line":12,"start":333,"end":344},{"type":"T_LCURLY","context":"normal","value":"{","line":12,"start":345,"end":346},{"type":"T_RETURN","context":"normal","value":"return","line":13,"start":349,"end":355},{"type":"T_LPAREN","context":"normal","value":"(","line":13,"start":356,"end":357},{"type":"T_IDENTIFIER","context":"normal","value":"dispatch","line":13,"start":357,"end":365},{"type":"T_COMMA","context":"normal","value":",","line":13,"start":365,"end":366},{"type":"T_IDENTIFIER","context":"normal","value":"getState","line":13,"start":367,"end":375},{"type":"T_RPAREN","context":"normal","value":")","line":13,"start":375,"end":376},{"type":"T_ARROW","context":"normal","value":"=>","line":13,"start":377,"end":379},{"type":"T_LCURLY","context":"normal","value":"{","line":13,"start":380,"end":381},{"type":"T_CONST","context":"normal","value":"const","line":14,"start":386,"end":391},{"type":"T_IDENTIFIER","context":"normal","value":"baz","line":14,"start":392,"end":395},{"type":"T_ASSIGN","context":"normal","value":"=","line":14,"start":396,"end":397},{"type":"T_IDENTIFIER","context":"normal","value":"getState","line":14,"start":398,"end":406},{"type":"T_LPAREN","context":"normal","value":"(","line":14,"start":406,"end":407},{"type":"T_RPAREN","context":"normal","value":")","line":14,"start":407,"end":408},{"type":"T_PERIOD","context":"normal","value":".","line":14,"start":408,"end":409},{"type":"T_IDENTIFIER","context":"normal","value":"baz","line":14,"start":409,"end":412},{"type":"T_IDENTIFIER","context":"normal","value":"dispatch","line":15,"start":417,"end":425},{"type":"T_LPAREN","context":"normal","value":"(","line":15,"start":425,"end":426},{"type":"T_LCURLY","context":"normal","value":"{","line":15,"start":426,"end":427},{"type":"T_TYPE","context":"normal","value":"type","line":15,"start":428,"end":432},{"type":"T_COLON","context":"normal","value":":","line":15,"start":432,"end":433},{"type":"T_STRING","context":"normal","value":"\"BAR\"","line":15,"start":434,"end":439},{"type":"T_COMMA","context":"normal","value":",","line":15,"start":439,"end":440},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":15,"start":441,"end":444},{"type":"T_COLON","context":"normal","value":":","line":15,"start":444,"end":445},{"type":"T_TRUE","context":"normal","value":"true","line":15,"start":446,"end":450},{"type":"T_RCURLY","context":"normal","value":"}","line":15,"start":451,"end":452},{"type":"T_RPAREN","context":"normal","value":")","line":15,"start":452,"end":453},{"type":"T_IDENTIFIER","context":"normal","value":"doSomethingAsync","line":16,"start":458,"end":474},{"type":"T_LPAREN","context":"normal","value":"(","line":16,"start":474,"end":475},{"type":"T_IDENTIFIER","context":"normal","value":"baz","line":16,"start":475,"end":478},{"type":"T_RPAREN","context":"normal","value":")","line":16,"start":478,"end":479},{"type":"T_PERIOD","context":"normal","value":".","line":17,"start":486,"end":487},{"type":"T_IDENTIFIER","context":"normal","value":"then","line":17,"start":487,"end":491},{"type":"T_LPAREN","context":"normal","value":"(","line":17,"start":491,"end":492},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":17,"start":492,"end":497},{"type":"T_ARROW","context":"normal","value":"=>","line":17,"start":498,"end":500},{"type":"T_LCURLY","context":"normal","value":"{","line":17,"start":501,"end":502},{"type":"T_IDENTIFIER","context":"normal","value":"dispatch","line":18,"start":510,"end":518},{"type":"T_LPAREN","context":"normal","value":"(","line":18,"start":518,"end":519},{"type":"T_LCURLY","context":"normal","value":"{","line":18,"start":519,"end":520},{"type":"T_TYPE","context":"normal","value":"type","line":18,"start":521,"end":525},{"type":"T_COLON","context":"normal","value":":","line":18,"start":525,"end":526},{"type":"T_STRING","context":"normal","value":"\"FOO\"","line":18,"start":527,"end":532},{"type":"T_COMMA","context":"normal","value":",","line":18,"start":532,"end":533},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":18,"start":534,"end":537},{"type":"T_COLON","context":"normal","value":":","line":18,"start":537,"end":538},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":18,"start":539,"end":544},{"type":"T_RCURLY","context":"normal","value":"}","line":18,"start":545,"end":546},{"type":"T_RPAREN","context":"normal","value":")","line":18,"start":546,"end":547},{"type":"T_RCURLY","context":"normal","value":"}","line":19,"start":554,"end":555},{"type":"T_RPAREN","context":"normal","value":")","line":19,"start":555,"end":556},{"type":"T_RCURLY","context":"normal","value":"}","line":20,"start":558,"end":559},{"type":"T_RCURLY","context":"normal","value":"}","line":21,"start":560,"end":561}],"errors":[{"id":"E1","messages":[{"id":"E1M1","description":"identifier `doSomethingAsync`","context":" doSomethingAsync(baz)","source":"-","start":{"line":16,"column":5,"offset":458},"end":{"line":16,"column":20,"offset":474}},{"id":"E1M2","description":"Could not resolve name","context":null,"source":null,"start":null,"end":null}],"operation":null}]}
Typing Redux reducers
Reducers take the state and
actions that we’ve typed and pulls them together for one method.
1
2
3
|
function reducer(state: State, action: Action): State {
}
|
{"value":"function reducer(state: State, action: Action): State {\n // ...\n}\n","tokens":[{"type":"T_FUNCTION","context":"normal","value":"function","line":1,"start":0,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"reducer","line":1,"start":9,"end":16},{"type":"T_LPAREN","context":"normal","value":"(","line":1,"start":16,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"state","line":1,"start":17,"end":22},{"type":"T_COLON","context":"type","value":":","line":1,"start":22,"end":23},{"type":"T_IDENTIFIER","context":"type","value":"State","line":1,"start":24,"end":29},{"type":"T_COMMA","context":"normal","value":",","line":1,"start":29,"end":30},{"type":"T_IDENTIFIER","context":"normal","value":"action","line":1,"start":31,"end":37},{"type":"T_COLON","context":"type","value":":","line":1,"start":37,"end":38},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":1,"start":39,"end":45},{"type":"T_RPAREN","context":"normal","value":")","line":1,"start":45,"end":46},{"type":"T_COLON","context":"type","value":":","line":1,"start":46,"end":47},{"type":"T_IDENTIFIER","context":"type","value":"State","line":1,"start":48,"end":53},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":54,"end":55},{"type":"Line","context":"comment","value":"// ...","line":2,"start":58,"end":64},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":65,"end":66}],"errors":[]}
You can also validate that you have handled every single type of action by
using the empty
type in your default
case.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
type State = { +value: boolean };
type FooAction = { type: "FOO", foo: boolean };
type BarAction = { type: "BAR", bar: boolean };
type Action = FooAction | BarAction;
function reducer(state: State, action: Action): State {
switch (action.type) {
case "FOO": return { ...state, value: action.foo };
case "BAR": return { ...state, value: action.bar };
default:
(action: empty);
return state;
}
}
|
{"value":"// @flow\ntype State = { +value: boolean };\n\ntype FooAction = { type: \"FOO\", foo: boolean };\ntype BarAction = { type: \"BAR\", bar: boolean };\n\ntype Action = FooAction | BarAction;\n\nfunction reducer(state: State, action: Action): State {\n switch (action.type) {\n case \"FOO\": return { ...state, value: action.foo };\n case \"BAR\": return { ...state, value: action.bar };\n default:\n (action: empty);\n return state;\n }\n}\n","tokens":[{"type":"Line","context":"comment","value":"// @flow","line":1,"start":0,"end":8},{"type":"T_TYPE","context":"normal","value":"type","line":2,"start":9,"end":13},{"type":"T_IDENTIFIER","context":"type","value":"State","line":2,"start":14,"end":19},{"type":"T_ASSIGN","context":"type","value":"=","line":2,"start":20,"end":21},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":22,"end":23},{"type":"T_PLUS","context":"type","value":"+","line":2,"start":24,"end":25},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":2,"start":25,"end":30},{"type":"T_COLON","context":"type","value":":","line":2,"start":30,"end":31},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":2,"start":32,"end":39},{"type":"T_RCURLY","context":"type","value":"}","line":2,"start":40,"end":41},{"type":"T_SEMICOLON","context":"type","value":";","line":2,"start":41,"end":42},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":44,"end":48},{"type":"T_IDENTIFIER","context":"type","value":"FooAction","line":4,"start":49,"end":58},{"type":"T_ASSIGN","context":"type","value":"=","line":4,"start":59,"end":60},{"type":"T_LCURLY","context":"type","value":"{","line":4,"start":61,"end":62},{"type":"T_TYPE","context":"normal","value":"type","line":4,"start":63,"end":67},{"type":"T_COLON","context":"type","value":":","line":4,"start":67,"end":68},{"type":"T_STRING","context":"type","value":"\"FOO\"","line":4,"start":69,"end":74},{"type":"T_COMMA","context":"type","value":",","line":4,"start":74,"end":75},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":4,"start":76,"end":79},{"type":"T_COLON","context":"type","value":":","line":4,"start":79,"end":80},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":4,"start":81,"end":88},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":89,"end":90},{"type":"T_SEMICOLON","context":"type","value":";","line":4,"start":90,"end":91},{"type":"T_TYPE","context":"normal","value":"type","line":5,"start":92,"end":96},{"type":"T_IDENTIFIER","context":"type","value":"BarAction","line":5,"start":97,"end":106},{"type":"T_ASSIGN","context":"type","value":"=","line":5,"start":107,"end":108},{"type":"T_LCURLY","context":"type","value":"{","line":5,"start":109,"end":110},{"type":"T_TYPE","context":"normal","value":"type","line":5,"start":111,"end":115},{"type":"T_COLON","context":"type","value":":","line":5,"start":115,"end":116},{"type":"T_STRING","context":"type","value":"\"BAR\"","line":5,"start":117,"end":122},{"type":"T_COMMA","context":"type","value":",","line":5,"start":122,"end":123},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":5,"start":124,"end":127},{"type":"T_COLON","context":"type","value":":","line":5,"start":127,"end":128},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":5,"start":129,"end":136},{"type":"T_RCURLY","context":"type","value":"}","line":5,"start":137,"end":138},{"type":"T_SEMICOLON","context":"type","value":";","line":5,"start":138,"end":139},{"type":"T_TYPE","context":"normal","value":"type","line":7,"start":141,"end":145},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":7,"start":146,"end":152},{"type":"T_ASSIGN","context":"type","value":"=","line":7,"start":153,"end":154},{"type":"T_IDENTIFIER","context":"type","value":"FooAction","line":7,"start":155,"end":164},{"type":"T_BIT_OR","context":"type","value":"|","line":7,"start":165,"end":166},{"type":"T_IDENTIFIER","context":"type","value":"BarAction","line":7,"start":167,"end":176},{"type":"T_SEMICOLON","context":"type","value":";","line":7,"start":176,"end":177},{"type":"T_FUNCTION","context":"normal","value":"function","line":9,"start":179,"end":187},{"type":"T_IDENTIFIER","context":"normal","value":"reducer","line":9,"start":188,"end":195},{"type":"T_LPAREN","context":"normal","value":"(","line":9,"start":195,"end":196},{"type":"T_IDENTIFIER","context":"normal","value":"state","line":9,"start":196,"end":201},{"type":"T_COLON","context":"type","value":":","line":9,"start":201,"end":202},{"type":"T_IDENTIFIER","context":"type","value":"State","line":9,"start":203,"end":208},{"type":"T_COMMA","context":"normal","value":",","line":9,"start":208,"end":209},{"type":"T_IDENTIFIER","context":"normal","value":"action","line":9,"start":210,"end":216},{"type":"T_COLON","context":"type","value":":","line":9,"start":216,"end":217},{"type":"T_IDENTIFIER","context":"type","value":"Action","line":9,"start":218,"end":224},{"type":"T_RPAREN","context":"normal","value":")","line":9,"start":224,"end":225},{"type":"T_COLON","context":"type","value":":","line":9,"start":225,"end":226},{"type":"T_IDENTIFIER","context":"type","value":"State","line":9,"start":227,"end":232},{"type":"T_LCURLY","context":"normal","value":"{","line":9,"start":233,"end":234},{"type":"T_SWITCH","context":"normal","value":"switch","line":10,"start":237,"end":243},{"type":"T_LPAREN","context":"normal","value":"(","line":10,"start":244,"end":245},{"type":"T_IDENTIFIER","context":"normal","value":"action","line":10,"start":245,"end":251},{"type":"T_PERIOD","context":"normal","value":".","line":10,"start":251,"end":252},{"type":"T_TYPE","context":"normal","value":"type","line":10,"start":252,"end":256},{"type":"T_RPAREN","context":"normal","value":")","line":10,"start":256,"end":257},{"type":"T_LCURLY","context":"normal","value":"{","line":10,"start":258,"end":259},{"type":"T_CASE","context":"normal","value":"case","line":11,"start":264,"end":268},{"type":"T_STRING","context":"normal","value":"\"FOO\"","line":11,"start":269,"end":274},{"type":"T_COLON","context":"normal","value":":","line":11,"start":274,"end":275},{"type":"T_RETURN","context":"normal","value":"return","line":11,"start":276,"end":282},{"type":"T_LCURLY","context":"normal","value":"{","line":11,"start":283,"end":284},{"type":"T_ELLIPSIS","context":"normal","value":"...","line":11,"start":285,"end":288},{"type":"T_IDENTIFIER","context":"normal","value":"state","line":11,"start":288,"end":293},{"type":"T_COMMA","context":"normal","value":",","line":11,"start":293,"end":294},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":11,"start":295,"end":300},{"type":"T_COLON","context":"normal","value":":","line":11,"start":300,"end":301},{"type":"T_IDENTIFIER","context":"normal","value":"action","line":11,"start":302,"end":308},{"type":"T_PERIOD","context":"normal","value":".","line":11,"start":308,"end":309},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":11,"start":309,"end":312},{"type":"T_RCURLY","context":"normal","value":"}","line":11,"start":313,"end":314},{"type":"T_SEMICOLON","context":"normal","value":";","line":11,"start":314,"end":315},{"type":"T_CASE","context":"normal","value":"case","line":12,"start":320,"end":324},{"type":"T_STRING","context":"normal","value":"\"BAR\"","line":12,"start":325,"end":330},{"type":"T_COLON","context":"normal","value":":","line":12,"start":330,"end":331},{"type":"T_RETURN","context":"normal","value":"return","line":12,"start":332,"end":338},{"type":"T_LCURLY","context":"normal","value":"{","line":12,"start":339,"end":340},{"type":"T_ELLIPSIS","context":"normal","value":"...","line":12,"start":341,"end":344},{"type":"T_IDENTIFIER","context":"normal","value":"state","line":12,"start":344,"end":349},{"type":"T_COMMA","context":"normal","value":",","line":12,"start":349,"end":350},{"type":"T_IDENTIFIER","context":"normal","value":"value","line":12,"start":351,"end":356},{"type":"T_COLON","context":"normal","value":":","line":12,"start":356,"end":357},{"type":"T_IDENTIFIER","context":"normal","value":"action","line":12,"start":358,"end":364},{"type":"T_PERIOD","context":"normal","value":".","line":12,"start":364,"end":365},{"type":"T_IDENTIFIER","context":"normal","value":"bar","line":12,"start":365,"end":368},{"type":"T_RCURLY","context":"normal","value":"}","line":12,"start":369,"end":370},{"type":"T_SEMICOLON","context":"normal","value":";","line":12,"start":370,"end":371},{"type":"T_DEFAULT","context":"normal","value":"default","line":13,"start":376,"end":383},{"type":"T_COLON","context":"normal","value":":","line":13,"start":383,"end":384},{"type":"T_LPAREN","context":"normal","value":"(","line":14,"start":391,"end":392},{"type":"T_IDENTIFIER","context":"normal","value":"action","line":14,"start":392,"end":398},{"type":"T_COLON","context":"type","value":":","line":14,"start":398,"end":399},{"type":"T_EMPTY_TYPE","context":"type","value":"empty","line":14,"start":400,"end":405},{"type":"T_RPAREN","context":"normal","value":")","line":14,"start":405,"end":406},{"type":"T_SEMICOLON","context":"normal","value":";","line":14,"start":406,"end":407},{"type":"T_RETURN","context":"normal","value":"return","line":15,"start":414,"end":420},{"type":"T_IDENTIFIER","context":"normal","value":"state","line":15,"start":421,"end":426},{"type":"T_SEMICOLON","context":"normal","value":";","line":15,"start":426,"end":427},{"type":"T_RCURLY","context":"normal","value":"}","line":16,"start":430,"end":431},{"type":"T_RCURLY","context":"normal","value":"}","line":17,"start":432,"end":433}],"errors":[]}
Flow + Redux resources