Technote

by sizuhiko

aws-sdk v3 で TS2345 が出てコンパイルエラーになる

dependabot で @aws-sdk/client のバージョンアップがコンパイルエラーになる

少し久しぶりの記事になってしまいましたが、この間も Node.js v18 / aws-sdk v3 への移行を行なっています。 一部のリポジトリではコードの移行は終わって、 dependabot でライブラリの最新追従を行なっているのですが、以下のようなコンパイルエラーが出るようになりました。

error TS2345: Argument of type 'typeof LambdaClient' is not assignable to parameter of type 'InstanceOrClassType<Client<ServiceInputTypes, MetadataBearer, any>>'.
  Type 'typeof LambdaClient' is not assignable to type 'ClassType<Client<ServiceInputTypes, MetadataBearer, any>>'.

aws-sdk v3 では複数の aws サービスを使っていると複数のパッケージに依存するようになるのですが、複数のバージョンアップが dependabot によって PR されるうち、一部のアプデだけ上記のようなエラーになります。

issue を探してみる

aws-sdk の issue を調べていくと、それっぽいものがありました。

Typescript compilation problems since 3.52.0 in lib-dynamodb

この issue 自体はクローズされていないのですが、コメントのスレッドの中に有用な情報がありました。

  • @aws-sdk/types が依存に入っていて、異なるバージョンの client-xxx があるとエラーになる(なんで package-lock.json を消してから npm i しなおすとうまくいくよ -> そんなんやるか!)
  • @aws-sdk/client-xxxx の各クライアントはすべて最新バージョンに追従してください

のようなものです(要約してあります)。

aws-sdk@v3 はサービスごとにパッケージを分割することで v2 と比べて良い、というのがウリなはずなんですが、これではパッケージ管理崩壊しているのでは?と思わなくもないですが、まぁ各クライアントのバージョンを合わせれば良いだけなので、従うことにしました。 ちなみにこの時点では複数の @aws-sdk/client-xxx を全て最新版に追従することで解消されました。

この問題が発生する状況

この問題が発生する状況は以下のとおりです。

  • すでに1つ以上の @aws-sdk/client-xxxx を入れていて、後日機能追加によって別のクライアントをインストールするとき
  • dependabot でパッケージごとにバージョンアップの PR が発動する

おすすめの対応

なので、現時点でのオススメの対応は以下のとおりです。

  • 新しく @aws-sdk/client-xxxx を追加するときは、既存のクライアントも含めてすべて同じバージョンに変更する
  • dependabot による更新を @aws-sdk/* については無効にする

Github Actions の dependabot でアプデを無効にするには、 dependabot.yml を以下のように記述すれば良いです。

version: 2
updates:
  - package-ecosystem: 'npm'
    directory: '/'
    ignore:
      - dependency-name: '@aws-sdk/*'
        # aws-sdk に対するすべての更新を無視

私たちは AWS Lambda の Node.js v18 ランタイムを使っているので、aws-sdk はランタイムにグローバルインストールされているから、あえて最新版に追従しなくても問題ないというのが主な理由です。 新しいクライアント追加のときに最新に追従すれば十分という判断です。

さいごに

aws-sdk@v3 を使ったアプリのナレッジが少ないので、何か小さなことでも記事にしていこうと思います。 同様の問題に遭遇した人の解決に役立てれば幸いです。