Open1

readonlyの配列フィールドをコンストラクタでObject.freezeするとTS4104が発生する

こばちきこばちき

readonlyの配列フィールドをコンンストラクタでObject.freezeすると、TS4104のエラーが発生する。
エラーメッセージは以下の通り。
The type 'readonly Construction[]' is 'readonly' and cannot be assigned to the mutable type 'Construction[]'.

export class Constructions {
  private readonly _constructions: Construction[] = [];

  constructor(constructions?: Construction[]) {
    if (constructions != null) {
      this._constructions = Object.freeze(constructions); // このthis._constructionsでTS4104が発生している
    }
  }
}

Object.freeze(constructions)の戻り値はreadonly Construction[]で、this._constructionsがreadonlyになっていないというメッセージに思えるのだが、readonlyとして定義している。

private readonly _constructions: Construction[] = [];

最近ReadonlyArrayという読み込み専用配列型があることを知ったので、そちらに変更したところ、エラーは消えた。

private _constructions: ReadonlyArray<Construction> = [];

サバイバルTypescriptの読み取り専用の配列 (readonly array)をよくよく見ると、readonlyの場所が違っていた。
正しくは以下の通りだった。

private _constructions: readonly Construction[] = [];

今後はReadonlyArrayを使うことにする。