Skip to content

Instantly share code, notes, and snippets.

@barbagrigia
Forked from anonymous/action-creators.js
Created October 7, 2017 16:41
Show Gist options
  • Save barbagrigia/2d73f1c0629f34c3845b88b4204b7c75 to your computer and use it in GitHub Desktop.
Save barbagrigia/2d73f1c0629f34c3845b88b4204b7c75 to your computer and use it in GitHub Desktop.
create tagged union from return types of action-creators
// @flow
// Helper to extract inferred return type of a function
type _ExtractReturn<B, F: (...args: any[]) => B> = B;
type ExtractReturn<F> = _ExtractReturn<*, F>;
// Use constants as normal
const AGE = 'AGE';
const NAME = 'NAME';
// only need to provide types for arguments in action-creators
// return type will be inferred
function setAge(age: number) {
return { type: AGE, payload: age }
}
function setName(name: number) {
return { type: NAME, payload: name }
}
type State = { age: number, name: string }
// Create a union type containing all the return types of
// of your chosen action-creators. The result can be used as a tagged
// union that allows flow to narrow the payload type based on 'type' property
type Actions =
ExtractReturn<typeof setAge> |
ExtractReturn<typeof setName>
function reducer(state: State = { age: 0, name: '' }, action: Actions): State {
switch(action.type) {
case AGE: {
// here, flow knows action.payload is a number
return {
...state,
age: action.payload,
}
}
case NAME: {
// here, flow knows action.payload is a string
return {
...state,
name: action.payload.toLowerCase(),
}
}
default: return state;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment