こんにちは。
個人開発でReactとTypeScriptを触ってstateの計算をしようとした際、想定外の型エラーが発生してしまったので備忘録として記事にしたいと思います。
型エラーが発生したコード
「stateの定数から1を加算し、その後ゼロパディングをする」という処理を試みたコードです。
sample1.tsx
const [minutes, setMinutes] = useState<number | string>(0);
const plus1Minutes = () => {
const plusNum = minutes + 1;
const padMinutes = plusNum.toString().padStart(2, "0");
setMinutes(padMinutes);
};
ですが、上記のコードだと以下のエラーが発生しました。
演算子 '+' を型 'string | number' および 'number' に適用することはできません。
次に定数plusNumの計算部分をNumber()で囲ってみましたが、結果は同じでした。
sample2.tsx
const [minutes, setMinutes] = useState<number | string>(0);
const plus1Minutes = () => {
const plusNum = Number(minutes + 1);
const padMinutes = plusNum.toString().padStart(2, "0")
setMinutes(padMinutes);
};
問題点
問題は計算式の+と文字列連結の+が混同していた点でした。
まずは単純な例で見てみます。
// 数字型同士を「加算」させているプラス
console.log(2 + 1);
// 文字型同士を「連結」させているプラス
console.log("test" + "01");
次にエラーが起きていたコードの抜粋です。
const [minutes, setMinutes] = useState<number | string>(0);
// minutesはnumber型かstring型か確定していない
const plusNum = minutes + 1;
この場合、minutes + 1は数値加算をしているのか文字列連結をしているかが明瞭でないためTS型エラーが起きているということでした。
対処例
明確に数値同士の加算としたい場合、stateの定数のみをNumber()で囲めば数値同士の計算として定義できました。
const [minutes, setMinutes] = useState<number | string>(0);
// minutesを数値型として明示すれば回避可能
const plusNum = Number(minutes) + 1;
さいごに
複数の型指定をするのは便利だと思っていた反面、今回のように型を1つに定めないとハマる落とし穴があることは気づきませんでした。
今後はより一層型定義について気を遣っていきたいです。