Code Fix

中級

文字列リテラルをenum型の引数に渡すとエラーになる理由

enumで定義した型は、見た目が近い文字列リテラルであっても別の型として扱われます。enumのメンバー名と同じ文字列を渡しても、enum型そのものの値でなければ代入・引数として受け付けられません。

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

main.ts(8,20): error TS2345: Argument of type '"Active"' is not assignable to parameter of type 'Status'.
main.ts
ファイル名
8
行番号
20
列番号 — この位置でtscが検査に失敗しました
TS2345
エラーコード — 検索するとTypeScriptの解説が見つかります
Argument of type '"Active"' is not assignable to parameter of type 'Status'.
内容 — 期待していたもの、または受け付けられなかったもの

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

パターン1

 1  enum Status {
 2    Active,
 3    Inactive,
 4  }
 5  function report(s: Status): string {
 6    return `status=${s}`;
 7  }
 8  console.log(report("Active"     ));
                             ^
main.ts(8,20): error TS2345: Argument of type '"Active"' is not assignable to parameter of type 'Status'.

"Active"はただの文字列であり、enumのStatus.Activeとは別の型です。メンバー名と同じ文字列を渡しても通用しません。

直し方: "Active"Status.Active にします。

この問題を解いてみる →

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

パターン2

 1  enum Color {
 2    Red,
 3    Blue,
 4  }
 5  function paint(c: Color): string {
 6    return `color=${c}`;
 7  }
 8  console.log(paint("Red"    ));
                          ^
main.ts(8,19): error TS2345: Argument of type '"Red"' is not assignable to parameter of type 'Color'.

文字列の"Red"とColor.Redは別の型です。enumのメンバーそのものを渡す必要があります。

直し方: "Red"Color.Red にします。

この問題を解いてみる →

パターン3

 1  enum Level {
 2    Low,
 3    High,
 4  }
 5  function setLevel(l: Level): string {
 6    return `level=${l}`;
 7  }
 8  console.log(setLevel("Low"    ));
                             ^
main.ts(8,22): error TS2345: Argument of type '"Low"' is not assignable to parameter of type 'Level'.

Level.Lowと文字列"Low"は別の型として扱われます。setLevelにはenumの値そのものを渡す必要があります。

直し方: "Low"Level.Low にします。

この問題を解いてみる →

よくある誤解

「enumのメンバー名と同じ文字列を渡せば通じるはず」という考えは誤りです。TypeScriptのenumは独自の名前的型(nominal-ishな型)を持ち、文字列リテラル型とは構造が似ていても別物として扱われます。

まとめ

文字列リテラルをenum型の引数に渡すとエラーになる理由は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

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