Immutableのフロータイプ定義を使用して、マップの形状を記述したいと思います。
オブジェクトの形状は次の方法で説明できます。
const stateShape: {
id: number,
isActive: boolean
} = {
id: 123,
isActive: true
};
Immutableのマップに似たようなものはありますか?
いいえ。ただし、レコードを使用すると、Flowで形状を型チェックできますが、型はチェックできません。
correct答えは次のようになります:no、マップには形状がないため(少なくともFlowおよびImmutableでは)。ただし、Immutableには、形状を持つ「マップ」のタイプがあります。それはRecordsです。ただし、以下に説明する理由により(厳密には関係ないため)、Immutable.Record
は非常に緩やかで、実際には形状をチェックしません。
Recordプロパティに直接アクセスする(おそらく不要な)機能を無視すると、より良いlibdefを作成できます。これは次のようになります。
declare class Record<T: Object> {
static <T: Object>(spec: T, name?: string): Record<T>;
get: <A>(key: $Keys<T>) => A;
set<A>(key: $Keys<T>, value: A): Record<T>;
remove(key: $Keys<T>): Record<T>;
}
この宣言を使用して、Recordの形状を定義できます。 ここでは動作しています 。ただし、実際の値のタイプを定義することはできません。フローは文書化されていない$PropertyType<T, K>
タイプ。オブジェクトT
と文字列リテラルK
を受け取ります。作る $PropertyType
私たちの場合、それは$Keys<T>
これは、ストリング共用体タイプです。数週間前、これを実現するための問題が公開されました。 ここにあります 。
フローでは、それらはかなり異なります。これは地図です:
type MyMaps = { [key: string]: number }
実際のキーは不明です。 Flowが知っている唯一のことは、すべてのキーが文字列であり、すべての値が数字でなければならないことです。一方、オブジェクトタイプは次のようになります。
type MyObject = { a: string, x: boolean }
タイプnewObj
FlowのオブジェクトMyObject
を作成または変更するとき、newObj.a
は文字列で、newObj.x
はブール値です。
レコードは、直接キーアクセスを通じてすべてのキー/値ペアを公開します。
type R = { a: string }
const r = Record({ a: 'Supa' })
r.a === r.get('a')
これには、r
の型定義がRecord<R>
およびR
(正確ではないが、十分に近い)。そう:
(r: R & Record<R>)
Flowにはオブジェクトとの交差タイプのサポートがないため、これは機能しません。 これが実際にどのように見えるか 。