Augmented Usamimi

it { is_expected.to be_blog.written_by(izumin5210) }

Immutable.RecordとFlow

Immutable.jsを導入するとやりたくなることランキング3位くらいに,Immutable.Recordを継承してモデルクラス的なものを作るというものがある.

また,Flowを利用してこのクラスに型定義をつけることができれば,さいきょうのモデルクラスを実装できる気がしてくる.Immutable.jsは自前でFlowの型定義ファイルを持ってるので実現も難しくなさそう.

Immutable.jsやFlowと同じくFacebook大先生のライブラリであるDraft.jsでも前述のようなモデルクラスを実装している(e.g. CharacterMetadata).

…が,じつはそんなにうまいこといかない(Try flow).

const defaultValue = {
  id: 1,
  title: "test",
};

type EntityConfig = typeof defaultValue;

const EntityRecord = Record(defaultValue);

class Entity extends EntityRecord {
}

const entity = new Entity();
entity.set("id", 1);
entity.get("aa", 0); // Should throw

上記のコードだと最後の行でエラー出てほしいけど,何も起きない.型定義は以下のようになっている.

//TODO: Once flow can extend normal Objects we can change this back to actually reflect Record behavior.
// For now fallback to any to not break existing Code
declare class Record<T: Object> {
  static <T: Object>(spec: T, name?: string): /*T & Record<T>*/any;
  get<A>(key: $Keys<T>): A;
  set<A>(key: $Keys<T>, value: A): /*T & Record<T>*/this;
  remove(key: $Keys<T>): /*T & Record<T>*/this;
}

型定義のコメントアウトを外してみる(Try flow).

//TODO: Once flow can extend normal Objects we can change this back to actually reflect Record behavior.
// For now fallback to any to not break existing Code
declare class Record<T: Object> {
  static <T: Object>(spec: T, name?: string): T & Record<T>;
  get<A>(key: $Keys<T>): A;
  set<A>(key: $Keys<T>, value: A): T & Record<T>;
  remove(key: $Keys<T>): T & Record<T>;
}

エラー出る.悲しい.

19: class Entity extends EntityRecord {
                         ^ identifier `EntityRecord`. Expected polymorphic type instead of any member of intersection type
19: class Entity extends EntityRecord {
                         ^ intersection

ぐぐったらSOでも似たような質問出てる.

This doesn't work because Flow lacks support for intersect types with objects. Here's how that looks in action. http://stackoverflow.com/a/39558931

痛ましい事件だったね….

References

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用