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; }
//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
- Immutable.js
- Flow | A static type checker for JavaScript
- Draft.js | Rich Text Editor Framework for React
WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用
- 作者: 柴田文彦
- 出版社/メーカー: インプレス
- 発売日: 2016/11/25
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る