TL;DR
- 同じ型のパラメータを連続して並べない。関数を正しく呼び出せているかが分からなくなる。
- 別々の型をパラメータに取るか、すべてのパラメータを 1 つのオブジェクトにまとめる。
内容
同じ型のパラメータが並ぶ問題
次の関数は number 型のパラメータが 5 つ並んでいる。
function drawRect(x: number, y: number, w: number, h: number, opacity: number) { ... }呼び出し側の drawRect(25, 50, 75, 100, 1) を見ても、引数を正しい順に渡せているかが分からない。
ただし例外もある。max(a, b) や isEqual(a, b) のように引数の順序を入れ替えても結果が変わらない場合や、arr.slice(start, stop) のように順序が自然な場合は問題にならない。とはいえ、何を自然と感じるかは開発者によって異なる。年月日の順序がその例である。
代替案 1: 別々の型をパラメータに取る
interface Point { x: number; y: number }
interface Dimension { width: number; height: number }
function drawRect(topLeft: Point, size: Dimension, opacity: number) { ... }
drawRect({ x: 25, y: 50 }, { width: 75, height: 100 }, 1.0)代替案 2: すべてのパラメータを 1 つのオブジェクトにまとめる
interface DrawRectParams extends Point, Dimension {
opacity: number
}
function drawRect(params: DrawRectParams) { ... }
drawRect({ x: 25, y: 50, width: 75, height: 100, opacity: 1.0 })パラメータが多すぎる場合
そもそもパラメータが多すぎるなら、リファクタリングして減らすべきである。
「10 個のパラメーターを持つ関数があったら、おそらく何らかの問題が見過ごされている」
パラメータ数の上限は、ESLint の max-params ルールで強制できる。
キーワード
自分の理解
代替案 2(すべてのパラメータを 1 つのオブジェクトにまとめる)をよく使っている。