-
-
Save barbagrigia/2d73f1c0629f34c3845b88b4204b7c75 to your computer and use it in GitHub Desktop.
create tagged union from return types of action-creators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @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