🍀

AWS CDKでundefined関係の型エラーが出る時の対処法

2024/10/19に公開

前書き

この記事を書いている途中でエラーメッセージに思いっきり原因が書かれていることに気付いたのですが、自分みたいな不注意な人間が他にも 1 人くらいはいるかもしれないので一応公開します
(だって今まで exactOptionalPropertyTypes 使ってなかったんだもん 😭)

結論

tsconfig の exactOptionalPropertyTypes: true が悪さをしているかもしれないのでこいつをどうにかしよう

問題

以下のような IAM Role を作成して Lambda に紐付けるという簡単な Stack ですが、2 箇所でエラーが発生します

import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import * as nodejs from "aws-cdk-lib/aws-lambda-nodejs";
import * as iam from "aws-cdk-lib/aws-iam";

export class CdkTmpStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const someRole = new iam.Role(this, "someRole", {
      // エラー発生
      assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
    });

    new nodejs.NodejsFunction(this, "someFunc", {
      functionName: "someFunc",
      // エラー発生
      role: someRole,
    });
  }
}

エラーの内容は 2 つとも同じような内容で以下のようなものです

// assumeBy
Type 'ServicePrincipal' is not assignable to type 'IPrincipal' with 'exactOptionalPropertyTypes: true'.
Consider adding 'undefined' to the types of the target's properties.
  Types of property 'principalAccount' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.ts(2375)

// role
Type 'Role' is not assignable to type 'IRole' with 'exactOptionalPropertyTypes: true'.
Consider adding 'undefined' to the types of the target's properties.
  Types of property 'principalAccount' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.ts(2375)

解決策

はい、 エラーメッセージに書かれている通り exactOptionalPropertyTypes: true が原因なので Stack の ts ファイルにこのオプションが効かなくなるようにすれば OK です

一番簡単なのは exactOptionalPropertyTypes: true を消す(false にする)ことですが、それだと関係無いところまで影響が出てしまう可能性があります(構成による)

そのため、自分は cdk/ などでディレクトリを切って配下に Stack などを置き、 cdk/tsconfig.jsonexactOptionalPropertyTypes: false で上書きするのがいいのかなと思いました

cdk/tsconfig.json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "exactOptionalPropertyTypes": false
  }
}

他にいい方法があれば教えてください!

Discussion