初めに
そもそも関数のオーバーロードってなんだろう?いろんな記事で扱われているので簡単に説明をしてみる。
function increment(num: string | number) {
if (typeof num === "string"){
return num + "000";
} else {
return num + 10;
}
}
const incre01 = increment("10");
console.log(incre01) // 10000
const incre02 = increment(10);
console.log(incre02) // 20
上記の処理は関数に渡す引数の値がstring型かnumber型かで処理を分けれるようにしている。
ここでincre01にカーソルを当てると下記の画像のようになる。
incre01の期待したい値はstring型なのにnumberも混ざってしまっている。。TypeScriptさん、そうじゃないんです。そのような時に型アサーションで
const incre01 = increment("10") as string;
という風にするのも一つの手段だと思われます。ただこちらの関数を何度も使う時に毎回型アサーションを使うのもどうなんだ??となる時に使うのがオーバーロードになるみたい。コードにすると下記のような感じ
function increment(num: string): string;
function increment(num: number): number;
function increment(num: string | number) {
if (typeof num === "string"){
return num + "000";
} else {
return num + 10;
}
}
const incre01 = increment("10");
console.log(incre01) // 10000
const incre02 = increment(10);
console.log(incre02) // 20
注目するべきなのは、
function increment(num: string): string;
function increment(num: number): number;
の部分で、
stringが来たらstringを返す。
numberが来たらnumberを返す。
という風にTypeScriptにエンジニアが実装をした意図の型をTypeScriptに伝えている形ですね。
オーバーロードを使っての感想
こちらはあくまで個人的な意見という事で。。
オーバーロードで型を伝えるというのはいい機能だと思っているのですが、そもそも異なる型が来てそれによって処理を分けるという事自体どうなんだろうという気がしている。(これは今回がstring と numberを使っているからかも。。)
関数の中でやっている処理がincrementという足すという事をしたとしても、やっていることが違うので関数を分けた方がいいのではと思った。。
2021/5/8に追記
こういうパターンは使える??
下記は一例。。
function execute(role: "normal"): "私はnormalユーザーです";
function execute(role: "admin"): "私はadminユーザーです";
function execute(role: "normal" | "admin") {
if (role === "normal"){
return "私はnormalユーザーです"
} else {
return "私はadminユーザーです"
}
}
const result = execute("normal")
最後に
こちら見ていただいてありがとうございました!
関数をオーバーロードに対して最後に否定的になってしまいましたが、『こんな感じで使ったらいいよ!』みたいな事があれば是非コメントよろしくお願いします!