-
-
Save anonymous/9ffb548a38b6c24114d4bad360bfe8f8 to your computer and use it in GitHub Desktop.
// @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; | |
} | |
} |
Love to see any improvements over this as I'm new to Flow
Can you elaborate on the ExtractReturn
and _ ExtractReturn
helpers? I'd like to use this technique to reduce my verbose typing however I'm still learning Flow and I don't fully understand how this works.
@shakyShane I'm not sure it actually works. Looking at the example I see the following:
function setName(name: number /* <- Supposed to be a string. */) {
return { type: NAME, payload: name }
}
setName
's argument is supposed to be a string
but it's currently not giving any errors, maybe I'm misunderstanding how this should work but to me this seems wrong.
in name is a string
, line 16
Using ExtractReturn
seems to have problems. For example, if adding the error:
const payload: boolean = action.payload;
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
vs string
).
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...
https://flow.org/try/#0PTAEAEDMBsHsHcBQJQAkCm0AO6BOoAXWUdADwNwEMBjA0ASwDtI9d0ATUNggV10cIBPHKFiRQlUJB6Na9WI0QFh6UAH0AouSq0ASul78APACEANKABiALlAAKAHRPKuAOYBnW5UaCA2gF0ASlAAXgA+UBMIkMiAbiUVUC0KGgJ9Q0YjS2j1ZJ00gz5MgCoLbPjkMABVd1VqBXcCbwJ3CVbGWFwAW0poRHrGRtAAQQBxDVDQAHIxjSn4gaGAOWGAWQmYqZX1+cRK0UZoQVBGdA5CYixcWAA3enZVZRxWyE6JNx4u9EYWhgFU+SMAC01DYlCIuHc+24RSEIng9Gg0FAACNVEwWLg2OxENJZARAaBagRhq50HZKGTbIxPmjcMEAN6IUAsriFfigBlw9C2WYWLCUQRwSjsLxk0AAX0QUtxMjkCiJBiWlC+dkYKp5J1peEZzNZMI5XKemu2Gn5guFopOGsl0r2xtAAGUmgRVDEuZTNTSunSLOqvrZGrgmK5bfsAMJg10SUAyQkOgZNJghiRIwgAC1UBoExtaYn2YlAglgfFA1HTsFq-3lwNB6HBnXcDlAABVM2z3DxoHRqN5UaoeLVOJRWpImq4yTiUHGFQR0+DU3B4C8lxdrViEBnVAKhbARdzUSPzgqpsapqArrAcLhlAkRMMa60QnqWXlUukikZjYXiaT0BEAB8XySbR33ZTJv3EYllS+MI9jxGs2XYHhqDwOxGnBTVnUwyYPSpUAAAY-Q1WwpnPCULABBReUfQJbGw6MmVZIkEQIcsKRrBxjV1ZjmN7WoRnGWwmN40SUEzNgLBgTcAGsOmXCROJ3S0GFHLUfTwYDRJZbNOS07TmKcBwMNdMx9IMllPS8JSLT3dgzIs1kpQM5ztP41RTWE8zePEvB0Ck1c5IQUcbN3fd6DUoMQ285jdJExzDKcEz-Ji7T-U1KjGAcZS7K42AABkEDwcMjzsQIHIS1zRKq3iHkgSguwIWxdOS+JmKlCUgA