Code Fix

中級

readonly配列にpushしようとするとdoes not exist on typeになる理由

readonly number[]のように宣言した配列型には、push・pop・splice等の破壊的(要素を変更する)メソッドがそもそも型として存在しません。呼び出そうとした時点で「そのメソッドは無い」というエラーになります。

エラーメッセージの読み方

main.ts(2,9): error TS2339: Property 'push' does not exist on type 'readonly number[]'.
main.ts
ファイル名
2
行番号
9
列番号 — この位置でtscが検査に失敗しました
TS2339
エラーコード — 検索するとTypeScriptの解説が見つかります
Property 'push' does not exist on type 'readonly number[]'.
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  function printAll(items: readonly number[]): void {
 2    items.push  (4);
               ^
 3    console.log(items);
 4  }
 5  printAll([1, 2, 3]);
main.ts(2,9): error TS2339: Property 'push' does not exist on type 'readonly number[]'.

readonly number[]にはpushのような破壊的メソッドは型として存在しません。concatのような非破壊的メソッドを使います。

直し方: pushconcat にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  function clearAll(items: readonly string[]): void {
 2    items.splice(0, items.length);
               ^
 3    console.log(items);
 4  }
 5  clearAll(["a", "b"]);
main.ts(2,9): error TS2551: Property 'splice' does not exist on type 'readonly string[]'. Did you mean 'slice'?

spliceは配列を直接書き換える破壊的メソッドです。readonly配列の型には含まれていません。

直し方: spliceslice にします。

この問題を解いてみる →

パターン3

 1  function reverseAll(items: readonly number[]): void {
 2    items.reverse();
               ^
 3    console.log(items);
 4  }
 5  reverseAll([1, 2, 3]);
main.ts(2,9): error TS2339: Property 'reverse' does not exist on type 'readonly number[]'.

reverseも元の配列を書き換える破壊的メソッドのため、readonly配列の型からは除外されています。

直し方: reverseslice にします。

この問題を解いてみる →

よくある誤解

「readonlyは実行時に書き換えを禁止する機能」だと誤解されがちですが、実際にはコンパイル時の型チェックだけの仕組みです。破壊的メソッド自体が型定義から除外されているため、呼び出しコードの時点でエラーになります。

まとめ

readonly配列にpushしようとするとdoes not exist on typeになる理由は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)