[TypeScript] 型定義モジュールの依存モジュールが更新されない場合の対処法

yarnで依存モジュールを管理しているプロジェクトで、とある型定義モジュール(@typed/module_name)のバージョンを上げたのですが、型定義モジュールの依存モジュールのバージョンが上がらず、tscでエラーになる事象に遭遇したので原因と対処をまとめておきます。

環境

  • yarn: 1.19.1
  • tsc: 3.7.2

再現方法

package.json に以下の2つの型定義モジュールが記述されているとします。

"devDependencies": {
    "@types/a": "1.0.0",
    "@types/b": "1.0.0",
  }
  • @types/a の依存モジュールはありません。
  • @types/b の依存モジュールは @types/a です。

このとき、 @types/a1.0.1 と、 @types/b1.0.1 がリリースされました。 そして、 @types/b1.0.1@types/a1.0.1 に依存しています。

そこで、 package.json を以下のように書き換えて yarn を実行します。

"devDependencies": {
    "@types/a": "1.0.1",
    "@types/b": "1.0.1",
  }

すると、 tsc を実行したときにエラーが起きるようになります。

原因

型定義モジュールの、依存モジュールのバージョンが指定されていないため。

そもそも、型定義モジュールの package.json は、 microsoft/types-publisher が動的に生成します。このとき、依存モジュールのバージョンは * として生成されます。

この状態で、再現方法の最初の package.json の状態で yarn を実行すると、 yarn.lock ファイルは以下のようになります。

"@types/a@*", "@types/a@1.0.0":
  version "1.0.0"

"@types/b@1.0.0":
  version "1.0.0"
  dependencies:
    "@types/a@" "*"

そして、再現方法の2番めの package.json の状態で yarn を実行すると、 yarn.lock ファイルは以下のように更新されます。

"@types/a@*":
  version "1.0.0"

"@types/a@1.0.1":
  version "1.0.1"

"@types/b@1.0.1":
  version "1.0.1"
  dependencies:
    "@types/a@" "*"

"@types/b@1.0.1" が依存する "@types/a@" "*" のバージョンが、 1.0.0 のままであることがお分かりいただけるかと思います。

この問題は、かなり前から 指摘されている のですが、解決されていません。そもそも依存モジュールを動的に検出しているのでバージョンの指定は不可能なように思います。また、型定義モジュールに package.json を含めることはできますが @types 以外のパッケージとREADMEにて説明されています

A package.json may be included to specify dependencies that are not other @types packages.

対処

原因は yarn.lock に記録されるバージョンのズレが問題なので、該当箇所の記述(上記の例では "@types/a@*" の部分)を削除してから、

"@types/a@*": # ここを消す
  version "1.0.0"

"@types/a@1.0.1":
  version "1.0.1"

"@types/b@1.0.1":
  version "1.0.1"
  dependencies:
    "@types/a@" "*"

再度 yarn を実行すると以下のようになり問題が解決します。

"@types/a@*", "@types/a@1.0.1":
  version "1.0.1"

"@types/b@1.0.1":
  version "1.0.1"
  dependencies:
    "@types/a@" "*"

別の対処

tsconfig.json の設定で skipLibCheck: true をすると型定義ファイル( *.d.ts )の型チェックがスキップされます。

まとめ

依存モジュールの依存モジュールがおかしい時は yarn.lock を確認しましょう!