web-dev-qa-db-ja.com

フローでImmutable.jsマップシェイプを記述する方法

Immutableのフロータイプ定義を使用して、マップの形状を記述したいと思います。

オブジェクトの形状は次の方法で説明できます。

const stateShape: {
  id: number,
  isActive: boolean
} = {
  id: 123,
  isActive: true
};

Immutableのマップに似たようなものはありますか?

40
William

TL; DR;

いいえ。ただし、レコードを使用すると、Flowで形状を型チェックできますが、型はチェックできません。

長い形式

correct答えは次のようになります:no、マップには形状がないため(少なくともFlowおよびImmutableでは)。ただし、Immutableには、形状を持つ「マップ」のタイプがあります。それはRecordsです。ただし、以下に説明する理由により(厳密には関係ないため)、Immutable.Recordは非常に緩やかで、実際には形状をチェックしません。

より良いレコードlibdef

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にはオブジェクトとの交差タイプのサポートがないため、これは機能しません。 これが実際にどのように見えるか

29
Kriegslustig