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