関数は、その引数の型が取りうる値を全てサポートする責任がある
例えば、3つのboolean型を引数に取る関数があった場合
code:ts
const f = (a: boolean, b: boolean, c: boolean) => {..}
booleanのinhabitantは2つなので、この関数fは、$ 2^3パターン全てを正常に処理する責務がある どんな組み合わせの3つが来たとしても処理を全うしないといけない
numberやstringだともっとパターン数が増える
numberが引数の場合、
負数も
0も
小数も
整数も
正数も
でけー数も
いずれが来ても正常に処理する必要がある
stringが引数の場合、
空文字も
1文字も、
なげー文字列も
いずれが来ても正常に処理する必要がある
recordの場合も同様で、
code:1.ts
type X = {
a: A1 | A2;
b: B1 | B2;
}
const f = (x: X) => {..}
以下の4パターンを正常に処理する必要がある
{ a: A1, b: B1}
{ a: A1, b: B2}
{ a: A2, b: B1}
{ a: A2, b: B2}
型が荒くなれば荒くなるほど、
サポートしないといけない組み合わせが増える
関数を定義する際に考えるべきこと
そもそも、その引数は全て必要なものか?
処理には不要なものが紛れ込んでいないか?
型を絞って許容するものを制限する
本当に数値全てを取るのか?
1|2|3で十分だったりはしないか
本当に文字列すべてを取るのか?
\`id${number}\`で表現できたりしないか
1.tsは本当に4パターンなのか?
本当に表現したかったのはこの2パターンではないのか?
code:2.ts
type X = { a: A1; b: B1 }
| { a: A2; b: B2 }
const f = (x: X) => {..}
動的型付き言語の場合、「どんな値が来ても大丈夫」になっている必要がある
というかそもそもそういう思想なので、逆に言えば実装者は考えなくても良い(そんなことはないが)
だからどんな値が来てもクラッシュせずに、なんか良い感じのエラーで処理される
それが開発者の意図に沿うものかどうか知らんけど
このとき、LoginButtonが対応しなければならないパターンは4パターンに増えます。例えば「colorが"red"でhasShadowがtrueのパターンは存在しないから実装をサボろう」のような考え方をしてはいけません
わかるmrsekut.icon