Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I write Flow type annotations for this function reducing an array of objects to an object

The following code declares a Flowtype Union of string in two ways. 1) Using the built-in Union Type, with the caveat of having to type all the codes again, creating a duplication. 2) Taking advantage of $Keys: Flow v0.38.0 correctly infers makeObjectWithKeys types, but I would like to know if it is possible to manually write such annotations.

const codesArray = [
   {
     name: 'Lorem',
     code: 'lm'
   },
   {
     name: 'Ipsum',
     code: 'ip'
   },
   // ...
 ]

// Define the CodeType "manually" with the Union built-in
type CodeTypeManual =
   | "lm"
   | "ip"
   // ...

const noErrorManual: CodeTypeManual = 'lm'
const flowErrorPropertyNotFoundManual: CodeTypeManual = 'zz'

// Define the CodeType by taking advantage of $Keys
const makeObjectWithKeys = (inArray) => { // Type annotations?
  return inArray.reduce(
        (objAcc, curObj) => { // Type annotations?
          const retObj = { ...objAcc }
          const { code } = curObj
          retObj[code] = code
          return retObj
        }
        , {}
  )
}
const objectWithCodesAsKeys = makeObjectWithKeys(codesArray)

type CodeType = $Keys<typeof objectWithCodesAsKeys>

let noError: CodeType = 'ip'
let flowErrorPropertyNotFound: CodeType = 'zz'
like image 867
robo-tt Avatar asked Mar 26 '26 12:03

robo-tt


1 Answers

If I understand your question correclty, this following might help.

/* @flow */
const codesArray = [
   {
     name: 'Lorem',
     code: 'lm'
   },
   {
     name: 'Ipsum',
     code: 'ip'
   },
   // ...
 ]

const makeObjectWithKeys = function<T: Object>(inArray: Array<T>, key: $Keys<T>) {
  return inArray.reduce((objAcc: { [name: typeof key]: T }, curObj: T) => {
    return Object.assign({}, objAcc, { [curObj[key]]: curObj })
  }, {})
}

const objectWithCodesAsKeys = makeObjectWithKeys(codesArray, 'code')
like image 89
David Avatar answered Mar 29 '26 01:03

David