はじめに
TypeScriptでTodoアプリを作って途中で、タイトルのようなエラーに遭遇しました。
現状
const [inCompleteTodos, setInCompleteTodos] = useState([]);
---- 中略 ----
const onClickAdd = () => {
if (inputTodo === "") return;
const newTodos = [...inCompleteTodos, inputTodo];
setInCompleteTodos(newTodos); //ここでエラー発生
setInputTodo("");
};
もともと、const [inCompleteTodos, setInCompleteTodos] = useState(["hoge"]);
このように"hoge"
という値を仮で入れていたのですが、削除したところエラーが出るようになりました。
useState([""])のように何かしら値を入れてみるとエラーは消えるのですが、上記写真のように余計な完了・削除
ボタンが表示されてしまいます。
結論
単純に、配列の中にどういう型の値が入ってくるか示されていなかったために起きたエラーで useState<string[]>([]);
のように明示的に<string[]>
を記述してあげたら望みの挙動を実現できました。
補足: neverとvoid
上記記事がわかりやすかったです。
fooやbarはvoid
、bazはnever
型になります。
voidはreturnでの戻り値がない
、というものに対して、neverはそもそもreturnしない
、というものになります。
ちなみに、fooのようにreturn
を書かなかった場合はundefined
が返ってきます。
const foo = () => {
}
const bar = () => {
return
}
const baz = () => {
while(true){}
}
let fooVar:never = foo() // error
let barVar:never = bar() // error
let bazVar:never = baz() //ok!