技術とかの雑なToday I Learnedメモ

分割代入のデフォルト引数

分割代入のデフォルト引数

JavaScript 分割代入な引数にデフォルト値を設定したい - かもメモ

Object の分割代入を引数で利用するのはよくやるんだけど、デフォルト引数を指定したいときにどうすればいいか悩ましくて調べた。

前にconst func = ({ hoge } = { hoge: '' }) => ...のように書いていたことがあるんだけど、これだと「特定のプロパティは必須だけどそれ以外は任意」みたいな分割代入の引数が受け取れなくなってしまう(はず)

と思って調べたら良い書き方があった。

const func = ({ hoge, fuga = '' } = {}) => ...

この記事でも言及されているけど、= {}の部分は必要なのか?と思ってしまう……。

実際、この= {}がない場合、引数に何も指定しなかったら実行時エラーになるらしい。が、TypeScript の場合は型チェックでエラーが出るのだろうか。

const func = ({ name, age = 20 } = {}) => {
  console.log(`名前: ${name} 年齢: ${age}`)
}

func() // "名前: undefined 年齢: 20"

となった。これは実行時エラーは出ないが意図しない結果になりそう。

const func = ({ name, age = 20 }: { name: string; age?: number }) => {
  console.log(`名前: ${name} 年齢: ${age}`)
}

func() //Expected 1 arguments, but got 0.(2554) input.tsx(15, 15): An argument matching this binding pattern was not provided.

こうすることで TS の型チェックに引っかかるようになった。

引数の型は age を Optional にしないとダメで、Optional にしていない場合は呼び出し時に age を絶対に指定しないとエラーになる。これは意図した挙動ではない。

つまり、JavaScript で書く場合は実行時エラーが起きないように= {}を使ってもいいかもしれないが、TypeScript で書くのであれば引数の型定義を書いた上でデフォルト値を設定するのがいい、ということが分かった。

TypeScript は偉大だ。