const arr1:number[] = [1,2];
const summaryFunc = (num1:number, num2:number) => num1 + num2;
summaryFunc(...arrr1);//エラー!
A spread argument must either have a tuple type or be passed to a rest parameter.ts(2556)
スプレッド引数は、タプル型を持つか、RESTパラメーターに渡される必要があります
こちらの記事が超わかりやすかったので、参考にさせていただきました(というかほぼほぼ日訳です)
エラーの原因
- 呼び出し元の関数の引数の型が
number
で固定されているから - 関数の引数がRESTパラメーターを許容しないから。
解決策
1. 配列の中身の型を明示してあげる(tupleとして宣言する)
const arr1:[number, number] = [1,2];
const summaryFunc = (num1:number, num2:number) => num1 + num2;
summaryFunc(...arr1);//3
2. 配列を読み取り専用にしてあげる
const arr1= [1,2] as const;
const summaryFunc = (num1,num2) => num1 + num2;
summaryFunc(...arr1);//3
readonlyにしているので、元の配列を追加したりすることはできなくなります。
arr1.push(3);//Property 'push' does not exist on type 'readonly [1, 2]'.ts(2339)
3. 関数にRESTパラメーターを受け取れるようにする
const arr1 = [1,2];
const summaryFunc =(...nums:number[]) => nums[0] + nums[1];
summaryFunc(...arr1);//3
これだったら配列の変更も効きますね。
ただし、関数の引数はnumber[]
のみ受け付けるようになるため、number
型を扱いたい場合は条件分岐させてあげないといけなさそうです。ただ、オプショナルパラメータでnull許容しているので実務ではあまり推奨されないんでしょうか・・・
この点、良い方法をお持ちでしたらぜひご教授お願いします!!
const summaryFunc =( num1?:number, num2?:number, ...nums:number[]) => {
if (num1 && num2){
return num1 + num2;
}else {
const copiedNums = [ ...nums];
return copiedNums[0] + copiedNums[1];
}
}
const arr1 = [1,2]
summaryFunc(...arr1);//3
ちなみに:JSだとどうなるか
const arr1 = [1,2]
const summaryFunc = (num1,num2) => num1 + num2;
summaryFunc(...arr1);//3
普通にいけます。。。
TypeScriptには入門したばかりですが、今後も学習を続けていきます。
本投稿で紹介した内容よりも、もっと良い方法、ご指摘あれば、ぜひぜひコメントお願いいたします。
参考