Code Fix

初級

文字列メソッドは元の文字列を変更せず新しい文字列を返す

toUpperCase()のような文字列メソッドは、呼び出し元の文字列そのものを書き換えるのではなく、変換後の新しい文字列を戻り値として返します。戻り値を使わずに呼び出しただけでは何も変わりません。

なぜエラーが出ないのか

出力: hello
(エラーなし)
TypeScriptは何も報告しません。型検査も構文も正しいためです
出力: hello
実際の挙動 — 期待した結果と食い違っている箇所
見つけ方
エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます

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

パターン1

 1  let s: string = "hello";
 2  s.toUpperCase();    
              ^
 3  console.log(s);
出力: hello

toUpperCase()は新しい文字列を返すだけで、sそのものは変わりません。sに代入し直す必要があります。

直し方: s.toUpperCase(); を s = s.toUpperCase(); にします。

この問題を解いてみる →

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

パターン2

 1  let name: string = "  Al  ";
 2  name.trim();       
             ^
 3  console.log(`[${name}]`);
出力: [ Al ]

trim()も新しい文字列を返すメソッドです。戻り値を使わなければ、元のnameの前後の空白は残ったままです。

直し方: name.trim(); を name = name.trim(); にします。

この問題を解いてみる →

パターン3

 1  let text: string = "a-b-c";
 2  text.replace("-", "_");       
                   ^
 3  console.log(text);
出力: a-b-c

replace()も非破壊的なメソッドです。戻り値を代入しなければ、textの中身は置換前のままです。

直し方: text.replace("-", "_"); を text = text.replace("-", "_"); にします。

この問題を解いてみる →

パターン4

 1  let s: string = "world";
 2  s.toUpperCase();    
              ^
 3  console.log(s);
出力: world

toUpperCase()は新しい文字列を返すだけで、sそのものは変わりません。

直し方: s.toUpperCase(); を s = s.toUpperCase(); にします。

この問題を解いてみる →

パターン5

 1  let t: string = " Hi ";
 2  t.trim();    
          ^
 3  console.log(`[${t}]`);
出力: [ Hi ]

trim()も新しい文字列を返すだけです。戻り値を使わなければtの前後の空白は残ります。

直し方: t.trim(); を t = t.trim(); にします。

この問題を解いてみる →

よくある誤解

「メソッドを呼べば元の変数の中身が変わるはず」という思い込みは、TypeScript・JavaScriptの文字列(プリミティブ値)には当てはまりません。文字列は不変(immutable)なので、変更後の値を使うには戻り値を代入し直す必要があります。

実務での勘所

配列にはpushやsortのように「自分自身を変更した上で何かを返す」メソッドが存在しますが、文字列の型定義(lib.d.ts)には、そもそも中身を書き換えるメソッドが1つも用意されていません。toUpperCaseもreplaceも、必ず新しい文字列を作って返すメソッドとして定義されています。配列の場合は「変更するメソッドの戻り値を誤解する」ことが問題になりますが、文字列の場合はそもそも「変更するメソッド」という選択肢自体が型定義の時点で存在しません。

演習をはじめる

関連するエラー

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