Created
September 10, 2017 20:38
-
-
Save anonymous/9ffb548a38b6c24114d4bad360bfe8f8 to your computer and use it in GitHub Desktop.
create tagged union from return types of action-creators
This file contains 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; | |
} | |
} |
I saw your SO question, dfroger. Thanks for reporting the issue.
I'm interested if anyone has found a way to reduce boilerplate, without sacrificing type safety? I'm looking to retrofit an existing codebase to use the ExtractReturn
util, but it introduces too many false negative type errors, which is greatly disappointing.
Still would love a way to clean up the type noise...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using
ExtractReturn
seems to have problems. For example, if adding the error:on line
32
, the error is catched.If added on line
39
, the error is not catched.Any idea how to fix it?
Related stackoverflow question.
Edit: this is not related to tye type of
name
(number
vsstring
).