データをまとめて管理する場合によく使う記述となります。
商品管理でのデータ構造を型指定したい場合で使います。
例: Todo 型の配列を useState で管理する場合
まず、Todo 型を定義します。
tstype Todo = {
id: number;
title: string;
completed: boolean;
};
次に、useState の呼び出しで型を指定します。
tsconst [todos, setTodos] = useState<Todo[]>([]);
解説
useState<Todo[]>([])の<Todo[]>は「Todo型の配列」を意味します。- 初期値は空配列
[]でも、型情報がTodo[]によって明確になるため、
TypeScript は以後todosの中身をTodo型の要素として扱います。
注意点
- 型推論に頼らず明示的に書くことで、保守性と可読性が向上します。
- 要素の構造が複雑な場合や、後から
setTodosに追加するデータが
わかりにくい場合も安全です。
ここで注目すべきは、
型の定義では”連想配列 {}”なのに
呼出し時は”配列 []”な
事です。
詳しく説明すると:
1. 定義の「連想配列」と呼出しの「配列」の違い
type Todo = { id: number; title: string; completed: boolean }
→ これは オブジェクトの型定義(いわゆる「連想配列」のように見える)です。Todo[]
→ これは「Todo型のオブジェクトが複数入った配列」という意味です。
つまり、Todoと定義したオブジェクトを配列で保管すると言う意味になり→Todo[]、
「連想配列(オブジェクト)を複数まとめた普通の配列」になります。
2. 例
tstype Todo = {で初期値は空
id: number;
title: string;
completed: boolean;
};
const [todos, setTodos] = useState<Todo[]>([]); //Todo型のオブジェクトが複数入った配列
// Todoを1件追加する
setTodos([...todos, { id: 1, title: "勉強する", completed: false }]);
この場合、todos の中身は以下のような配列になります:
ts[
{ id: 1, title: "勉強する", completed: false }
]
ここでの todos は「Todo 型のオブジェクトの配列」なので、
TypeScript の型定義と完全に一致しています。
まとめ
Todoは1件の「連想配列」的なオブジェクトの型Todo[]はその「オブジェクトの配列」- 呼び出し時に配列になっていても、型として全く問題ありません。
Reactでの”useStateの型の書き方”と覚えるのが一番です。
参考までに
eventの型も記述
type Props = {
onClick: (event: React.MouseEvent<HTMLInputElement>) => void
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void
onkeypress: (event: React.KeyboardEvent<HTMLInputElement>) => void
onBlur: (event: React.FocusEvent<HTMLInputElement>) => void
onFocus: (event: React.FocusEvent<HTMLInputElement>) => void
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void
onClickDiv: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
}

