🍑

use 関数をコンポーネントで使ったら型がおかしい

2021/08/13に公開

エラー内容

以下のようなエラーがでた。

この式は呼び出し可能ではありません。
  型 'number | Dispatch<SetStateAction<number>>' のすべての構成要素が呼び出し可能なわけではありません。
    型 'number' には呼び出しシグネチャがありません。

コードは以下の通り。

use 関数

import { useState } from 'react'

export const useTax = (
  _tax: number,
) => {
  const [price, setPrice] = useState(1000)
  const [value] = useState<number>(_tax)

  const tax = () => Math.floor(price * (1.0 + value / 100))

  return [price, tax, setPrice]
}

component

import { useTax } from '../compositions/useTax'
const AlertMessageOfTax = (props) => {
  const [price, tax, setPrice] = useTax(10)

  return (
    <div className="alert alert-primary h5">
			{/* ここで発生 */}
      <p className="h5">通常税率: {tax()}</p>
    </div>
  )
}

tax が () => number 型になっていて欲しいのに number | React.Dispatch<React.SetStateAction<number>>という型になっていてる。

解決策

use 関数の返り値に型を当てると直った。返り値にしっかり型を当ててやらないと、配列の中の型が or でまとめられてしまうため発生したっぽい。

use 関数

返り値に型を追加

import { useState } from 'react'

export const useTax = (
  _tax: number,
): [
  number,
  () => number,
  React.Dispatch<React.SetStateAction<number>>
] => {
  const [price, setPrice] = useState(1000)
  const [value] = useState<number>(_tax)

  const tax = () => Math.floor(price * (1.0 + value / 100))

  return [price, tax, setPrice]
}

Discussion