配列・オブジェクトの型定義とは
TypeScriptの配列・オブジェクトの型定義とは、変数の中身がどんなデータ構造になっているかをあらかじめ決めておく書き方です。実務でもっとも書く機会が多い型の一つなので、基本を押さえておくと学習効率が上がります。


なぜ配列・オブジェクトにも型定義が必要なのか
JavaScriptでは、配列やオブジェクトに何を入れても自由でした。
// JavaScript
const numbers = [1, 2, 3];
numbers.push("kino"); // 数値の配列のはずが、文字列も入ってしまうこの自由さは便利な反面、意図しないデータが紛れ込んでもエラーにならないという弱点があります。TypeScriptで型を決めておけば、こうした混入をコードを書いている段階で防げます。
配列の型定義の書き方
配列の型は、主に2通りの書き方があります。
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ["kino", "syounen"];number[]とArray<number>は、どちらも「number型の値だけが入る配列」という同じ意味です。どちらを使っても動作は変わらないので、社内やチームで書き方を統一しておくと読みやすくなります。個人的には、シンプルな型[]の方をよく使っています。
オブジェクトの型定義の書き方
オブジェクトの型は、プロパティ名とその型を1つずつ列挙する形で定義します。
type User = {
name: string;
age: number;
};
const user: User = {
name: "kino",
age: 30,
};この書き方については、interfaceとの使い分けも含めて別記事で詳しく解説しています。
オプショナルプロパティ(?)の使い方
プロパティによっては、「あってもなくてもいい」という場合があります。そのときは、プロパティ名の後ろに?を付けます。
type User = {
name: string;
age: number;
nickname?: string; // なくてもOK
};
const user1: User = { name: "kino", age: 30 }; // nicknameを省略してもエラーにならない
const user2: User = { name: "kino", age: 30, nickname: "きの" }; // これもOKプロフィール情報のように「必須ではない項目」を扱う場面でよく使う書き方です。
readonlyで書き換えを防ぐ
「一度セットしたら変更されたくない」というプロパティには、readonlyを付けられます。
type User = {
readonly id: number;
name: string;
};
const user: User = { id: 1, name: "kino" };
user.id = 2; // Error: Cannot assign to 'id' because it is a read-only property.データベースのIDのように、後から書き換わってほしくない値に付けておくと、意図しない上書きをコードの段階で防げます。
配列とオブジェクトを組み合わせた型
実務では、配列とオブジェクトを組み合わせた「オブジェクトの配列」を扱う場面が非常に多いです。
type User = {
name: string;
age: number;
};
const users: User[] = [
{ name: "kino", age: 30 },
{ name: "syounen", age: 20 },
];User[]は「User型のオブジェクトが並んだ配列」という意味です。APIから複数件のデータを受け取るときなど、非常によく登場する形です。API通信で受け取ったデータに型を付ける方法は、こちらの記事も参考にしてください。
実務での使用例:Reactでの一覧表示
Reactで一覧を表示する場合、User[]のようなオブジェクトの配列をmapで展開するのが定番の書き方です。
function UserList({ users }: { users: User[] }) {
return (
<ul>
{users.map((user) => (
<li key={user.name}>{user.name}({user.age}歳)</li>
))}
</ul>
);
}usersの型が決まっているおかげで、user.nameやuser.ageを書くときにエディタの入力補完が効き、タイプミスにもすぐ気づけます。
よくあるエラー
const user: User = { name: "kino" };
// Property 'age' is missing in type '{ name: string; }' but required in type 'User'.これは、必須のはずのageプロパティが渡されていないために起きるエラーです。もし本当に省略可能なプロパティなら、先ほど紹介した?を付けて解決します。省略できないなら、値を渡し忘れているだけなので、そのまま追加すればOKです。
よくある質問
Q. number[]とArray<number>はどちらを使えばいいですか?
A. 意味は同じなので、どちらでも構いません。チームやプロジェクトで書き方を統一するのがおすすめです。
Q. オプショナルプロパティとreadonlyは併用できますか?
A. できます。readonly nickname?: string;のように組み合わせて書けます。
Q. オブジェクトの配列はどんな場面でよく使いますか?
A. APIから複数件のデータを取得したときや、Reactで一覧表示を行うときに頻繁に登場します。
まとめ
- 配列は
型[]、オブジェクトはプロパティを列挙する形で型定義する - あってもなくてもいいプロパティには
?を付ける - 書き換えを防ぎたいプロパティには
readonlyを付ける - オブジェクトの配列(User[]など)は実務で非常によく使う形
公式ドキュメントにも、配列やオブジェクトの型についての解説があります。
▶ TypeScript公式ドキュメント:Everyday Types






