TSの基礎
Typeよりinterfaceを使うことがTS公式で推奨されてる
その理由はinterfaceは拡張性があって、その挙動がJSのobjectのようやから。
個人的には使い分けが重要やと感じた。逆に固定で決めたいobjectがあるならむしろ
Typeで固定した方が後に問題ならんし、無闇矢鱈にinterfaceにしてると拡張しまくってバグの温床になりそうと感じた。
Because an interface more closely maps how JavaScript objects work by being open to extension, we recommend using an interface over a type alias when possible.
Argument of type '' is not assignable to parameter of type 'SetStateAction<[]>'. エラーが出て解決できなかった話
結果見返すとエラー内容に全部書いてたのだが、TS初心者で、Reactでフロントエンドの開発の知見もなかったゆえ詰まってしまった。。。
先週まで型いい型最高と言ってたが、策士策に溺れるのように型好き型に惑わされる、な一週間であった。。。
そして改めてエラー内容は全てを物語ってるので、ちゃんとエラー内容を読んで「どこがそのエラー内容の状態になってるか」を分析・調査するのが大事やなと思った。
※当たり前のことなんやけど、新しい言語・libを使ってると自分が無知やから何か使用方法が間違ってんやと思ってしまって、無闇矢鱈にググって、いろいろ試してしまった。。。
これをしっかり反省して、ちゃんとエラー分を読んで分析しようと改めて思った。。(エラーで詰まるたびに毎回思ってる。。気がする。。まじでちゃんとこれを徹底しよう。エラー分析フローシートでも作ろう)
エラーは読んでそれに合わせて考えてググってんやけどねー、振り返れば分析・考察が足りてなかったなと思う。あくまで結果論やけど。。
error 内容
# Argument of type 'タイプ名' is not assignable to parameter of type 'SetStateAction<タイプ名[]>'.
Argument of type 'Work' is not assignable to parameter of type 'SetStateAction<Work[]>'.
TL; DR
axiosでrequestした際にresponseの型を宣言するけど、そこで[]
配列にしてなかったのが問題やった。
上記errorが出てた際のsrc code
type Work = {
id: number;
uuid: string;
userName: string;
profileImageUri: string;
text: string;
resourceUri: string;
isPublic: boolean;
};
const initialState : Work[] = []
const [works, setWorks] = useState(initialState);
useEffect(() => {
// ログインしてないなら、ログインページへリダイレクト
currentUser === null && props.history.push("/login");
getWorks({ uuid: currentUser?.uid })
.then(response => {
setWorks(response.data); // ここにsetWorksでresponse.data埋めれやんよと怒られてた。
return response.data;
})
.catch(err => {
console.log(err);
});
}, [currentUser]);
// 中略
const getWorks = useCallback(async (params: { uuid: string | undefined }) => {
return await api.get<Work>( // 結論左記が問題だった。。
`${API_URL}/users/${params.uuid}/followings/works`
);
}, []);
// 中略
{<div>
<ul>
{works.map((work, index) => (
<li key={index}>{work.text}</li>
))}
</ul>
</div>}
エラー解決し、APIのresponseをlist表示させれた際のsrc
type Work = {
id: number;
uuid: string;
userName: string;
profileImageUri: string;
text: string;
resourceUri: string;
isPublic: boolean;
};
const initialState : Work[] = []
const [works, setWorks] = useState(initialState);
useEffect(() => {
// ログインしてないなら、ログインページへリダイレクト
currentUser === null && props.history.push("/login");
getWorks({ uuid: currentUser?.uid })
.then(response => {
setWorks(response.data); // ここにsetWorksでresponse.data埋めれやんよと怒られてた。
return response.data;
})
.catch(err => {
console.log(err);
});
}, [currentUser]);
// 中略
const getWorks = useCallback(async (params: { uuid: string | undefined }) => {
return await api.get<Work[]>( // 左記をlist(Work[])にすれば一発やった。
`${API_URL}/users/${params.uuid}/followings/works`
);
}, []);
// 中略
{<div>
<ul>
{works.map((work, index) => (
<li key={index}>{work.text}</li>
))}
</ul>
</div>}