🦔

React Hook Formでregister()に変数を渡すと型エラーになったときの対処

2021/06/28に公開

事象

TypeScriptでReact Hook Formのregister()に変数を渡すと型エラーになる。

エラー文の例:

Argument of type 'string' is not assignable to parameter of type '"name" | "email"'.  TS2345

原因

React Hook FormのVersion7からregister()が文字列ではなく文字列リテラルしか受け付けなくなったから。

type InputSampleType = {
  firstName: string
  lastName: string
}

const InputSample = () => {
  const { register } = useForm<InputSampleType>()
  
  // string
  const firstName: string = 'firstName'
  // string literal
  const lastName = 'lastName'
  return (
    <div>
      // エラーになる
      <input {...register(firstName)} />
      // エラーにならない
      <input {...register(lastName)} />
    </div>
  )
}

上記の例だとさほど困らないが、ループ処理でregister()を使いたいときにかなり困る。

対処

調べてみたがテンプレート構文を文字列リテラルに変換する方法が見つけられなかったので、インデックスシグネチャを使って以下のように指定する。

エラーは回避できるが、どのような文字列でもregister()できてしまうためにあまり良くない。

type InputSampleType = {
  [key: string]: string
}

const InputLoop = () => {
  const { register } = useForm<InputSampleType>()
  const questions = ['question1', 'question2']
  const lists = questions.map((q, index) =>
   <input key={q} {...register(`testName${index}`)} />
  )

  return <div>{lists}</div>
}

参考

https://stackoverflow.com/questions/66978473/react-hook-form-usefieldarray-typescript-error-on-input-name/66978617#66978617

https://stackoverflow.com/questions/66967241/argument-of-type-string-is-not-assignable-to-parameter-of-type-string

Discussion