TypeScriptの配列・オブジェクトの型定義とは?書き方を初心者向けに解説

TypeScriptの配列・オブジェクトの型定義とは?書き方を初心者向けに解説

 

配列・オブジェクトの型定義とは

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

少年A
文字列とか数値の型は分かったけど、配列とかオブジェクトはどう書けばいいの?
キノ
実はここが一番実務で使う頻度が高いところだから、今日はここだけに絞って整理してみよう
スポンサーリンク

なぜ配列・オブジェクトにも型定義が必要なのか

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.nameuser.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

少年A
配列とオブジェクト、思ったよりシンプルだったかも
キノ
うん。ここが分かると、実務のコードの大半は読めるようになるよ

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です