flow
flowtype

flowtypeで存在しないkeyを取り出すときに型エラーを出す

以下のようなジェネリックな関数を定義します。
$Keysを使いオブジェクトのキーを検査します。
これだけでは、実用性があるかはわかりませんが、特定の場合に便利なときがあります。

function getObj<V: Object, O: { [*]: V }, K: $Keys<O>>(obj: O, key: K): V {
  return obj[key]
}

こんな感じで使えます。

function getObj<V: Object, O: { [*]: V }, K: $Keys<O>>(obj: O, key: K): V {
  return obj[key]
}

type User = { name: string }

const user1: User = { name: 'aclie' }
const user3: User = { name: 'bob' }

const users = { id1: user1, id3: user3 }

const v1 = getObj(users, 'id1')
const v2 = getObj(users, 'id2')
const v3 = getObj(users, 'id3')

id2は定義されてないので、型エラーが発生します。

 23: const v2 = getObj(users, 'id2')
                ^^^^^^^^^^^^^^^^^^^^ function call
 23: const v2 = getObj(users, 'id2')
                              ^^^^^ property `id2`. Property not found in
  7: function getObj<V: Object, O: { [*]: V }, K: $Keys<O>>(obj: O, key: K): V {
                                                  ^^^^^^^^ object literal

しかし、データを取り出すために一度関数を通す必要があり取り回しが悪いです。

{ [key: string]: Object }のようなマップオブジェクトのキーの検査は現状諦めています。
もし知見があれば、コメントまたはTwitterまで教えてください。