オプション引数 (optional parameter)
オプション引数(optional parameter)は、渡す引数を省略できるようにするTypeScript固有の機能です。オプション引数は疑問符?を引数名の後ろに書くことで表現します。
オプション引数の構文
tsfunction関数名 (引数名 ?:型 ) {}// ^オプション引数の標示
tsfunction関数名 (引数名 ?:型 ) {}// ^オプション引数の標示
オプション引数は、関数を呼び出すときに引数が省略できます。
tsfunctionhello (person ?: string) {}hello (); // 引数を省略して呼び出せるhello ("alice"); // 省略しない呼び出しももちろんOK
tsfunctionhello (person ?: string) {}hello (); // 引数を省略して呼び出せるhello ("alice"); // 省略しない呼び出しももちろんOK
省略するとundefinedになる
オプション引数の型は、型とundefinedのユニオン型になります。ユニオン型は日本語で言うと「いずれか」の意味です。上の例では、引数personはstring | undefined型になります。
tsfunctionhello (person ?: string) {}
tsfunctionhello (person ?: string) {}
引数を省略した場合、オプション引数の実行時の値はundefinedになります。
tsfunctionhello (person ?: string) {console .log (person );}hello ();
tsfunctionhello (person ?: string) {console .log (person );}hello ();
オプション引数の取り回し
オプション引数は、型がundefinedとのユニオン型になるため、そのままでは使えません。たとえば、次のコードはstringのtoUpperCaseメソッドを呼び出すコードです。これはコンパイルエラーになります。なぜなら、personがundefined型である可能性があるからです。そして、undefinedにはtoUpperCaseメソッドがありません。
tsfunctionhello (person ?: string) {return "Hello " +'person' is possibly 'undefined'.18048'person' is possibly 'undefined'.. person toUpperCase ();}
tsfunctionhello (person ?: string) {return "Hello " +'person' is possibly 'undefined'.18048'person' is possibly 'undefined'.. person toUpperCase ();}
この問題を解消するには、次の2つの方法があります。
デフォルト値を代入する
引数がundefinedの場合分けをif文で書き、そこでデフォルト値を代入する方法です。
tsfunctionhello (person ?: string) {if (typeofperson === "undefined") {person = "anonymous";}return "Hello " +person .toUpperCase ();}
tsfunctionhello (person ?: string) {if (typeofperson === "undefined") {person = "anonymous";}return "Hello " +person .toUpperCase ();}
Null合体代入演算子??=でデフォルト値を代入する方法もあります。
tsfunctionhello (person ?: string) {person ??= "anonymous";return "Hello " +person .toUpperCase ();}
tsfunctionhello (person ?: string) {person ??= "anonymous";return "Hello " +person .toUpperCase ();}
さらに、デフォルト引数を指定することでも同じことができます。多くのケースでは、デフォルト引数を使うほうがよいです。
tsfunctionhello (person : string = "anonymous") {// ^^^^^^^^^^^^^デフォルト引数return "Hello " +person .toUpperCase ();}
tsfunctionhello (person : string = "anonymous") {// ^^^^^^^^^^^^^デフォルト引数return "Hello " +person .toUpperCase ();}
📄️ デフォルト引数
引数の値がundefinedのとき、代わりの値を指定できるのがデフォルト引数(default parameter)です。
処理を分ける
オプション引数を取り回すもうひとつの方法は、処理を分けることです。
tsfunctionhello (person ?: string) {if (typeofperson === "undefined") {return "Hello ANONYMOUS";}return "Hello " +person .toUpperCase ();}
tsfunctionhello (person ?: string) {if (typeofperson === "undefined") {return "Hello ANONYMOUS";}return "Hello " +person .toUpperCase ();}
T | undefinedとの違い
オプション引数はユニオン型T | undefinedとして解釈されます。であれば、引数の型をT | undefinedと書けば同じなはずです。なぜTypeScriptは、疑問符?という別の記法を用意したのでしょうか。違いがあるのでしょうか。
これには呼び出す側で、引数を省略できるかどうかという違いが生まれます。オプション引数は引数自体を省略できますが、T | undefined型の引数は引数が省略できません。
たとえば、次のオプション引数の関数は引数なしで呼び出せます。
tsfunctionhello (person ?: string) {}hello (); // 引数を省略して呼び出せる
tsfunctionhello (person ?: string) {}hello (); // 引数を省略して呼び出せる
一方、次のようなundefinedとのユニオン型の引数は、引数なしではコンパイルエラーになります。
tsfunctionhello (person : string | undefined) {}Expected 1 arguments, but got 0.2554Expected 1 arguments, but got 0.hello ();
tsfunctionhello (person : string | undefined) {}Expected 1 arguments, but got 0.2554Expected 1 arguments, but got 0.(); hello
この関数を呼び出すためには、undefinedを渡す必要があります。
tsfunctionhello (person : string | undefined) {}hello (undefined );
tsfunctionhello (person : string | undefined) {}hello (undefined );
オプション引数の後に普通の引数は書けない
オプション引数は必ず最後に書かなければいけません。次のようにオプション引数より後ろに普通の引数を書くと、コンパイルエラーになります。
tsfunctionA required parameter cannot follow an optional parameter.1016A required parameter cannot follow an optional parameter.func (foo ?: string,: string) {} bar
tsfunctionA required parameter cannot follow an optional parameter.1016A required parameter cannot follow an optional parameter.func (foo ?: string,: string) {} bar