はじめに
TypeScriptの勉強中に型エラーが出ました(´;ω;`)
この記事は、学習の過程でまとめた備忘録です。内容の誤りや改善点があれば、コメントでご指摘いただけると大変ありがたいです。一緒に正確な情報を作り上げていただけると嬉しいです!
問題
先にエラー内容を紹介
Type '{ type: "title" | "time"; value: string | number; setState: Dispatch<SetStateAction<string>> | Dispatch<SetStateAction<number | "">>; }' is not assignable to type 'IntrinsicAttributes & InputProps'.
Type '{ type: "title" | "time"; value: string | number; setState: Dispatch<SetStateAction<string>> | Dispatch<SetStateAction<number | "">>; }' is not assignable to type 'TimeProps'.
Types of property 'type' are incompatible.
Type '"title" | "time"' is not assignable to type '"time"'.
Type '"title"' is not assignable to type '"time"'.
背景
入力欄のinputとhandleInputをセットにして定義したらきれいになるかなと思い、コンポーネントを作成することにしました。しかし、入力欄はタイトルと時間の二つあり、それぞれで扱うstateの型は異なりました、、
そこでinputのvalueやsetStateはユニオンで受け取れば一つのコンポーネントでどちらも管理できそう!と思い、Propsは以下のように定義しました。
type TitleProps = {
type: "title";
value: string;
setState: React.Dispatch<React.SetStateAction<string>>;
};
type TimeProps = {
type: "time";
value: number | "";
setState: React.Dispatch<React.SetStateAction<number | "">>;
};
export type InputProps = TitleProps | TimeProps;
で、普段通り関数コンポーネントの一番上あたりで分割代入して、、と書いていたらエラーが起きてしまいました
解決方法
if文でtypeごとに分岐させてから分割代入する!
- props.type で分岐する
- そのブロック内で分割代入する
// 数字入力の分岐
if (props.type === "time") {
const {value, setState} = props
/* value, setStateを使った処理
~
~
*/
// 文字入力の分岐
} else {
const {value, setState} = props
/* value, setStateを使った処理
~
~
*/
}
いきなり分割代入すると型の対応関係がくずれるようです。
おわりに
TypeScriptの勉強を始めてから、JavaScriptでやっていた実装方法だとうまくいかないみたいなことがよく出てきます。
型をつけただけで、コードの書かせ方をこんなに操れるのすごいですね