JavaScriptにはないTypeScript独自の型あれこれTypeScriptのTypeあれこれシリーズ(2)

altJS、すなわち、JavaScriptの代わりとなる言語の筆頭である「TypeScript」。TypeScriptという言語名が示す通り、JavaScriptに「Type」、つまり、型の概念を持ち込んだものです。本連載では、このTypeScriptの型に関して、さまざまな方向から紹介していきます。連載1回目の前回は、基本中の基本に当たる、型指定にまつわるあれこれを紹介しました。今回はJavaScriptにはない、TypeScript独自の型のあれこれを紹介します。

» 2021年11月22日 05時00分 公開

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「TypeScriptのTypeあれこれシリーズ」のインデックス

連載:TypeScriptのTypeあれこれシリーズ

配列の要素と型

 配列はTypeScriptオリジナルなものではなく、JavaScript由来のものです。配列のTypeScriptらしい使い方から紹介していきましょう。

JavaScriptの配列の問題点

 JavaScriptで配列変数を用意する場合、リスト1のようなコードを記述します。

const array = [];
リスト1

 このarrayに対して、リスト2のように各要素を格納するコードを記述したとします。

array[0] = 35;  // (1)
array[1] = "こんにちは";  // (2)
array[2] = new Date();  // (3)
リスト2

 (1)では数値を、(2)では文字列を、(3)ではオブジェクトを、それぞれ要素として格納しています。これらのコードは、全て問題なく動作します。

 しかし、配列は本来、同種のデータをまとめておくためのものであり、同種のものがまとまっているからこそ、便利になるような仕組みがあります。例えば、JavaScriptの配列には、「reduce()」というメソッドがあり、これを使うと、リスト3のようなコードで簡単に数値配列の合計を計算できます。

const numArray = [1, 2, 3, 4, 5];
const sum = numArray.reduce(function(prev, current, i, arr) {
	return prev + current;
});
リスト3

 ただし、あくまでも配列が数値で構成されている場合にしか使えません。リスト2のarrayのように、数値以外のものを要素とする配列の場合は、当然、合計値になりません。しかも、JavaScriptでは、このようなコードを簡単に防ぐ方法がありません。

TypeScriptの配列

 一方、TypeScriptには、データ型という仕組みがあるので、配列に対しても、データ型を指定することで、このような問題を防ぐことができます。TypeScriptの配列構文は次の通りです。

[構文1]配列宣言
const 配列変数名: 各要素のデータ型[]

 リスト2のarrayを数値型に限定するならば、リスト4のようなコードになります。

const array: number[] = [];
array[0] = 35;
リスト4

 これで、配列変数arrayの各要素には数値以外代入できなくなります。もし、「こんにちは」を代入しようとすると、図1のようなエラーになります(以下、「Visual Studio Code」を利用)。

図1 数値型配列に文字列を代入しようとしてエラーになった画面

 TypeScriptの配列では、型指定のおかげで各要素の型が同一になります。同種のデータをまとめておくもの、という配列本来の働きを実現できるのです。

配列宣言には別の形がある

 配列を宣言する構文は、構文1とは異なるものがあります。

[構文2]配列宣言
const 配列変数名: Array<各要素のデータ型>

 リスト4を構文2で書き換えると、リスト5になります。

const array: Array<number> = [];
array[0] = 35;
リスト5

 通常、1つのプロジェクト内では、構文1と構文2のどちらかに統一しておけばよいでしょう。以降の解説では、より簡素に記述できる構文1を使います。

 なお、構文2にある「< >」という記述を、「ジェネリクス」といいます。ジェネリクスに関しては、今後、本連載中で扱う予定です。

再代入不可な配列と不変な配列の違い

 JavaScriptでもTypeScriptでも、変数をconstで宣言すると、再代入が不可になります。しかし、配列の各要素の改変では再代入になりません。例えば、リスト6のようなコードは問題なく動作します。

const array1: number[] = [1, 3, 5, 7, 9];
array1[4] = 11;  // (1)
array1[5] = 13;  // (2)
リスト6

 (1)では既存の要素の変更しており、(2)では新しい要素を追加しています。このどちらも可能です。一方、const宣言配列への再代入とは、リスト7のようなコードを指します。

array1 = [2, 4, 6, 8, 10];
リスト7

 この場合は、図2のようなエラーになります。

図2 const宣言配列へ再代入しようとしてエラーとなった画面

 つまり、const宣言配列は、再代入不可ではありますが、不変(イミュータブル)ではないのです。もし、不変の配列を作成するなら、「readonly」を利用します。例えば、リスト8のようなコードです。

const array2: readonly number[] = [1, 3, 5, 7, 9];
リスト8

 このarray2の各要素を変更しようとすると、図3のエラーになります。

図3 readonlyが付いた配列の要素を変更しようとしてエラーとなった画面

配列とタプルの違いは

 同種のデータをまとめておくものが配列なら、異種のデータをまとめておく方法にはどのようなものがあるのでしょうか。JavaScriptには古くからオブジェクトというものがあります。モダンなJavaScriptでは、クラスの利用も考えられます。オブジェクトもクラスも当然、TypeScriptで利用できます。ここでは、TypeScriptならではの方法として、もっと簡易に異種データをまとめることができる「タプル」を紹介します。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。