LoginSignup
2
1

More than 3 years have passed since last update.

MST(mobx-state-tree) でコンパイル(tsc)が激重になったり、出力 *.d.ts が激デカになったりしたら

Posted at

TL;DR

MSTのモデル定義を下記のように書き換えましょう。

書き換え前
export const ModelA = types.model("ModelA", {/**/})
書き換え後
const model = types.model("ModelA", {/**/})

type ModelA_InferredType = typeof model
export interface ModelA_ModelType extends ModelA_InferredType {}
export const ModelA: ModelA_ModelType = model

モデルの型を型推論そのままをexportせずに、きちんと名前がついた型としてexportするのがポイントです。

(参考: https://github.com/mobxjs/mobx-state-tree/issues/1425)

なぜ上記のように書き換えるのか

TypeScriptは型を推論できます。

そして、その型推論の上にmobx-state-treeのようなライブラリは成り立っているわけですが、推論された型は基本的に名前を持ちません。

たとえば、下記の ModelA の型はなんでしょうか?

export const ModelA = types.model("ModelA", {
  name: types.string
})

// 答え
IModelType<{ name: ISimpleType<string>, {}, _NotCustomized, _NotCustomized }>

では、下記の ModelB の型はどうなっているでしょうか?

export const ModelB = types.model("ModelB", { a: ModelA })

// 答え
IModelType<{
  a: IModelType<{ name: ISimpleType<string>, {}, _NotCustomized, _NotCustomized }>
}, {}, _NotCustomized, _NotCustomized >

では、下記の ModelC の型はどうなっているでしょうか?

export const ModelC = types.model("ModelB", { a: ModelA, b: ModelB })

// 答え
IModelType<{
  a: IModelType<{ name: ISimpleType<string>, {}, _NotCustomized, _NotCustomized }>;
  b: IModelType<{
    a: IModelType<{ name: ISimpleType<string>, {}, _NotCustomized, _NotCustomized }>
  }, {}, _NotCustomized, _NotCustomized >
}, {}, _NotCustomized, _NotCustomized >

なんか辛くなってきましたね。でも、なんで辛いのでしょうか?

それは、モデルの型に名前がついていないからです。たとえば、 ModelA の型について、いちいち a: IModelType<{ name: ISimpleType<string>, {}, _NotCustomized, _NotCustomized }> という型が出てきて非常に煩雑になっています。

仮にこれが ModelA_ModelType という名前だったなら、 ModelC の型は、下記のように非常にすっきりします。

IModelType<{
  a: ModelA_ModelType;
  b: IModelType<{
    a: ModelA_ModelType
  }, {}, _NotCustomized, _NotCustomized >
}, {}, _NotCustomized, _NotCustomized >

同じことが tsc のコンパイルにも言えます。

今の tsc (3.8.3時点) はコンパイル途中経過およびコンパイル出力結果において、 型推論結果に名前がない場合、型推論の大きな型を持ち回り、いちいちその型を展開して利用します。

MSTの場合、単純なモデルではこれは大きな問題になりませんが、複雑なネストを持つモデルを持ち始めた瞬間、上記の巨大な型をtscが用いるようになるので、コンパイル時間が簡単に膨れ上がります。

私のケースでは、ビルド時間が 1分程度 → 1時間弱にまで成長しました。また、複雑なモデルを参照しているだけの20行程度のファイルが、2000行の型ファイルにコンパイルされていました。

まとめ

MSTのようにメソッドチェーン+型推論で型を成長させていくライブラリの場合、型推論結果に名前をつけずにそのまま使っていると、いつかTypeScriptコンパイラが死にます。

(コンパイラ側で適度なところで名前をつけるなり、何とかしてほしいですが…。)

気をつけましょう。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1